您的当前位置:首页Angular中使用Resolve守卫实现预先获取路由组件所需数据

Angular中使用Resolve守卫实现预先获取路由组件所需数据

2024-08-12 来源:乌哈旅游

        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官网中关于路由相关的内容:。

因篇幅问题不能全部显示,请点此查看更多更全内容