如何仅预加载其父母已激活的模块?

时间:2018-07-13 20:54:31

标签: angular angular-routing

我实现了延迟加载。我正在尝试设置一个custom preloading strategy

说我具有以下网址结构:

/
/fruit
/fruit/bananas
/fruit/apples
/vegetables

如果我打/,我想预加载/fruit。按照Angular示例,我只需将data: {preload: true}放入路由配置中,然后实施自定义的预加载策略即可检查数据和加载。效果很好。

但是,在我实际上导航/bananas之前,我不想预加载/apples/fruit。照原样,/fruit一旦被预加载,预加载策略就会找到更多带有{preload: true}的模块,并且也预加载/bananas/apples

导航到其父模块之后,是否有一种清除预加载模块的干净方法?

1 个答案:

答案 0 :(得分:4)

最终,我使用了路由的data属性来提供一个自定义但可扩展的解决方案。我创建了3个属性:

  • preload(布尔值)-如果为true,则在Angular知道后立即预加载(例如/fruit)。这是Angular在他们的文档中给我们的基本示例
  • preloadCheckpoint(枚举)-我在自己的枚举中定义每个应用程序“检查点”。因此,在我的问题示例中,/fruit是检查点,我将在其上定义data: {preloadCheckpoint: myCheckpointEnum.FRUIT}
  • preloadAfterCheckpoint(枚举)-我将其定义为推迟预加载,直到到达某个检查点为止。如果我在/bananas上定义了它,直到定义了带有FRUIT检查点的路由,香蕉模块才会加载

我订阅了更改路线的信息,因此可以随时更新检查点列表,然后在每次尝试预加载时检查该列表。

export class CustomPreloadingStrategy implements PreloadingStrategy {
  checkpoints: Set<PreloadCheckpoints> = new Set<PreloadCheckpoints>(); 

  constructor(router: Router, route: ActivatedRoute){

    router.events.pipe(
     filter(event => event instanceof NavigationEnd),
      map(() => route),
      map(route => {
        while (route.firstChild) route = route.firstChild; //gets the deepest child
        return route;
      }),
      filter(route => route.outlet === 'primary'))
      .subscribe((route) => {
         if(route.snapshot.data['preloadCheckpoint'] !== undefined){ 
           this.checkpoints.add(route.snapshot.data['preloadCheckpoint']);
         }
    });
  }

  preload(route: Route, load: () => Observable<any>): Observable<any> {    
    if (route.data && ( route.data['preload'] || this.checkpoints.has(route.data['preloadAfterCheckpoint']) )){
      return load(); //preload this route
    } else {
      return of(null);
    }
  }
}

export enum PreloadCheckpoints {
  FRUIT
}