Angular官网中描述的使用resolve守卫主要解决的问题如下:
如果你在使用真实 api,很有可能数据返回有延迟,导致无法即时显示。 在这种情况下,直到数据到达前,显示一个空的组件不是最好的用户体验,最好使用解析器预先从服务器上获取完数据,这样在路由激活的那一刻数据就准备好了,还要在路由到此组件之前处理好错误。总之,你希望的是只有当所有必要数据都已经拿到之后,才渲染这个路由组件。
学习Angular项目实现的网易云首页如下:
在首页home组件中dom渲染时需要获取轮播图、热门标签、热门歌单、入驻歌手等信息,如果不使用reslove守卫,在进入页面时需要调用这四个获取数据的接口,代码如下:
ngOnInit() {
this.getBanners(); // 获取轮播图数据
this.getHotTags(); // 获取热门标签
this.getPersonalizedSheetList(); // 获取热门歌单
this.getEnterSingers(); // 获取入驻歌手
}
这样的结果就是会出现文章开始时所说的问题,下边是使用resolve优化后的代码。
1、首先要创建resolve服务,也就是下图的home-resolve.service.ts文件,该服务要实现一个Resolve接口,在默认的resolve()方法中返回home首页需要的四个接口数据:
type HomeDataType = [Banner[], HotTag[], SongSheet[], Singer[]]; // 定义返回的数据接口、依次为轮播对象数组、热门标签对象数组、热门歌单对象数组、歌手对象数组
@Injectable()
export class HomeResolveService implements Resolve<HomeDataType> {
constructor(private homeService: HomeService,
private singerService: SingerService,
private memberServe: MemberService,
private storageServe: StorageService) {}
resolve(): Observable<HomeDataType> {
return forkJoin([ // Rxjs操作符,主要是合并返回Observable
this.homeService.getBanners(),
this.homeService.getHotTags(),
this.homeService.getPersonalSheetList(),
this.singerService.getEnterSingers()
]).pipe(first()); // first操作符取数据流的第一个数据
}
}
2、需要在home-routing.module.ts对应的路由模块中对应的home路由对象中加入resolve守卫的配置:
const routes: Routes = [{
path: 'home',
component: HomeComponent,
data: {title: '发现'},
resolve: { homeDatas: HomeResolveService} // 路由配置resolve守卫
}];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [HomeResolveService]
})
export class HomeRoutingModule { }
3、home.component.ts中获取路由返回的数据:
constructor(private router: ActivatedRoute,
private route: Router,
private sheetService: SheetService,
private memberServe: MemberService,
private stroe$: Store<AppStoreModule>,
private batchActionsServe: BatchActionsService) { }
ngOnInit() {
this.router.data.pipe(map(res => res.homeDatas)). // router对象中返回的Observable中获取homeDatas属性即为resolve定义的对象数组,并赋值给组件中定义的对象供模板使用
subscribe(([banners, hotTags, songSheets, singers]) => {
this.banners = banners;
this.hotTags = hotTags;
this.songSheets = songSheets;
this.singers = singers;
});
}
这样就完成了Angular中resolve守卫的使用,在home组件渲染的时候四个接口的数据已经获取到,就不会出现文章开始时介绍的相关问题。详细学习可以参考Angular官网中关于路由相关的内容:。
因篇幅问题不能全部显示,请点此查看更多更全内容