手动调用Angular PreloadingStrategy的preload方法

时间:2019-05-29 07:09:08

标签: angular angular-routing

假设,我们有两个名为(Careworker / Client)的模块。在“客户端”模块中,我们有一个名为“(客户端配置文件)”的模块。这样,SelectiveStrategyService不会加载模块,只会存储该模块的名称。这就是为什么它无法访问(client-profile-module)名称的原因。

在下面的服务(SelectiveStrategyService)中,我们将跟踪这些路由,但是与其立即调用load函数,我们将其存储在字典中,以便以后可以访问它。

import { Injectable } from '@angular/core';
import { Route, PreloadingStrategy } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

@Injectable()
export class SelectiveStrategyService implements PreloadingStrategy {
  routes: { [name: string]: { route: Route; load: Function } } = {};

  preload(route: Route, load: Function): Observable<any> {

    if (route.data && route.data['preload']) {
      // load();
      this.routes[route.data.name] = {
        route,
        load
      };
    }

    return Observable.of(null);
  }

  preLoadRoute(name: string) {
    const route = this.routes[name];
    if (route) {
      route.load();
    }
  }

}

app.routing.module.ts:

const routes: Routes = [
  {
    path: "careworker", loadChildren: "app/careworker/careworker.module#CareworkerModule",
    data: { preload: false, name: "careworker-module" }
  },
  {
    path: "client", loadChildren: "app/client/client.module#ClientModule",
    data: { preload: true, name: "client-module" }
  }
];

client.routing.module.ts:

const routes: Routes = [
  {
    path: "index", component: ClientIndexComponent
  },
  {
    path: "profile",
    loadChildren: "app/client/client-profile/client-profile.module#ClientProfileModule",
    data: { preload: true, name: "client-profile-module" }
  }
];

SelectiveStrategyService只是服务,因此可以像其他任何服务一样将它们注入到我们的组件中:

constructor(private loader: SelectiveStrategyService) {}

更新:

在路由Dictionary中,必须有3个键(careworker-module,client-module和client-profile-module),但只有2个键(careworker-module,client-module)。这就是为什么我无法手动调用Client Profile模块的原因:

ngOnInit() {
  this.loader.preLoadRoute('client-profile-module');
}

不用说我可以很容易地调用preLoadRoute('client-module;),并且可以正常使用

  this.loader.preLoadRoute('client-module');

1 个答案:

答案 0 :(得分:0)

您需要实施自己的自定义预加载策略。创建一个实现PreloadingStrategy接口的类,然后在其中添加逻辑。您可以从route读取data对象,然后根据该对象执行一些逻辑。

export class AppPreloadingStrategy implements PreloadingStrategy {
    preload(route: Route, load: Function): Observable<any> {
        const loadRoute = (delay) => delay
            ? timer(150).pipe(flatMap(_ => load()))
            : load();
        return route.data && route.data.preload 
            ? loadRoute(route.data.delay)
            : of(null);
      }
}

然后在您的代码中使用这种新策略,例如

RouterModule.forRoot(routes, { 
   preloadingStrategy: AppPreloadingStrategy
})

如果发生模块负载,则没有撤消的意义。您可以手动调用尚未加载的路由的预加载。