Angular2无法使用Lazy模块加载自定义重用策略

时间:2017-02-22 05:42:07

标签: angular routes lazy-loading reusability

我尝试在angular2项目中使用custom reuse strategy, 但我发现它不适用于延迟模块加载。 谁知道这个?我的项目是角度2.6.4

重用strategy.ts

import {RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle} from "@angular/router";

export class CustomReuseStrategy implements RouteReuseStrategy {

    handlers: {[key: string]: DetachedRouteHandle} = {};

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldDetach', route);
        return true;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        console.debug('CustomReuseStrategy:store', route, handle);
        this.handlers[route.routeConfig.path] = handle;
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldAttach', route);
        return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        console.debug('CustomReuseStrategy:retrieve', route);
        if (!route.routeConfig) return null;
        return this.handlers[route.routeConfig.path];
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
        return future.routeConfig === curr.routeConfig;
    }

}

app.module.ts

const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'heroes', loadChildren: 'app/hero-list.module#HeroListModule' },
  { path: '',   redirectTo: '/crisis-center', pathMatch: 'full' }
];
@NgModule({
  imports: [ ... ],
  declarations: [ ... ],
  providers:[
    {provide: RouteReuseStrategy, useClass: CustomReuseStrategy}
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

然后我将<input>放到了两个组件上并进行了测试。

存储CrisisListComponent中的输入值,但不保留HeroListComponent lazy-loaded的值。

我不知道它还没有得到支持。 谢谢你的帮助。

5 个答案:

答案 0 :(得分:10)

RouteReuseStrategy适用于LazyLoaded组件。

这里的问题是您使用route.routeConfig.path作为存储和检索句柄的键。

我不知道为什么,但是对于LazyLoaded模块,执行route.routeConfig.path

shouldAttach为空

我使用的解决方案是在我的路线中定义自定义键,例如:

{ path: '...', loadChildren: '...module#...Module', data: { key: 'custom_key' } }

可以在ActivatedRouteSnapshot中轻松访问此键值,例如:

route.data.key

使用此键,您可以正确存储和检索手柄。

答案 1 :(得分:1)

使用此ReuseStrategy

import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
export class CustomReuseStrategy implements RouteReuseStrategy {

  private handlers: {[key: string]: DetachedRouteHandle} = {};


  constructor() {

  }

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return true;
  }

  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    this.handlers[route.url.join("/") || route.parent.url.join("/")] = handle;
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!this.handlers[route.url.join("/") || route.parent.url.join("/")];
  }

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    return this.handlers[route.url.join("/") || route.parent.url.join("/")];
  }

  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig;
  }

}

答案 2 :(得分:1)

使用此自定义重用策略文件进行延迟模块加载

import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';

/** Interface for object which can store both:
 * An ActivatedRouteSnapshot, which is useful for determining whether or not you should attach a route (see this.shouldAttach)
 * A DetachedRouteHandle, which is offered up by this.retrieve, in the case that you do want to attach the stored route
 */
interface RouteStorageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class CustomReuseStrategy implements RouteReuseStrategy {

    handlers: {[key: string]: DetachedRouteHandle} = {};

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldDetach', route);
        return !!route.data && !!(route.data as any).shouldDetach;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        console.debug('CustomReuseStrategy:store', route, handle);
        this.handlers[route.data['key']]= handle;
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldAttach', route);
        return !!route.data && !!this.handlers[route.data['key']];
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        console.debug('CustomReuseStrategy:retrieve', route);
        if (!route.data) return null;
        return this.handlers[route.data['key']];
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
        return future.data === curr.data;
    }

}

答案 3 :(得分:1)

使用这个。它使用组件名称作为存储和检索句柄的键。

$.post(....)

答案 4 :(得分:0)

要使其正常工作,您应该考虑完整路径,而不是像大多数文章所建议的那样简单的 route.routeConfig.path 。例如:

private getKey(route: ActivatedRouteSnapshot): string {
    return route.pathFromRoot
        .map((el: ActivatedRouteSnapshot) => el.routeConfig ? el.routeConfig.path : '')
        .filter(str => str.length > 0)
        .join('');
}

store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    this.handlers[this.getKey(route)] = handle;
}