子模块中的RouteReuseStrategy

时间:2017-04-19 08:22:53

标签: angular routing

这是我的懒惰加载子模块:

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(acnpRoutes),
    ....
  ],
  declarations: [...],
  providers: [
    {provide: RouteReuseStrategy, useClass: ACNPReuseStrategy}
  ]
})
export class AddCustomerNaturalPersonModule {
}

路线:

const acnpRoutes: Routes = [
  {
    path: '',
    component: AddCustomerNaturalPersonComponent,
    children: [
      {
        path: 'stepOne',
        component: ACNPStepOneComponent
      },
      {
        path: 'stepTwo',
        component: ACNPStepTwoComponent
      },
    ]
  }
]

和ACPNReuseStrategy:

export class ACNPReuseStrategy implements RouteReuseStrategy {
  handlers: {[key: string]: DetachedRouteHandle} = {}

  shouldDetach(route: ActivatedRouteSnapshot): boolean  {
    console.log(1)
    return true;
  }

  store(route: ActivatedRouteSnapshot, handle: {}): void {
    console.log(2)
  }

  ...

  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    console.log(5)
  }
}

不幸的是,ACNPReuseStrategy方法中的这些console.log都没有被触发。这是为什么?是否可以在延迟加载的模块中重用组件?

2 个答案:

答案 0 :(得分:2)

TL; DR 在主模块中提供RouteReuseStrategy而不是子模块(默认情况下为app.module.ts)。然后,在key中为每条路线分配route.data,以区分您的路线。

我最近也遇到过这个问题。我的子模块安装在主应用程序路径下,如下所示:

..., {    // in app.route.ts
          path: 'apimarket',
          canActivate: [DeveloperResolve],
          loadChildren: './apimarket/apimarket.module#ApiMarketModule'
}

如果我在子模块RouteReuseStrategy中提供自定义的ApiMarketModule,则永远不会构建RouteReuseStrategy

解决方案是在主模块中提供策略而不是子模块(在我的情况下为app.module.ts)。然后,您的RouteReuseStrategy将被正确构建。

但是,由于您的子路由route.routeConfig.path是相对路径,因此策略无法按预期工作。要解决此问题,我的解决方案是为我的路线分配一个唯一的key,如下所示:

export const apimarketRoutes: Routes = [
    {
        path: '',
        component: ApiMarketComponent,
        data: {
            shouldReuse: true,
            key: 'apimarketroot'
        }
    },
    {
        path: ':id',
        component: ContentPageComponent,
    }
];

这是我的RouteReuseStrategy实施FYR

export class MyRouteReuseStrategy implements RouteReuseStrategy {
  handlers: {[key: string]: DetachedRouteHandle} = {};

  constructor() {
    console.log('constructed');
  }

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    if (!route.data['shouldReuse']) {
      return null;
    }
    console.log('Attach cached page for: ', route.data['key']);
    return this.handlers[route.data['key']];
  }

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

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return !!route.data['shouldReuse'];
  }

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

  shouldReuseRoute(future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean {
    return !!future.data['shouldReuse'];
  }
}

RouteReuseStrategy没有详细记录,由于策略在根级别工作,我的解决方案可能存在潜在的性能问题。欢迎讨论:))

答案 1 :(得分:0)

首先,您必须了解什么是 future curr .eg:从 127.0.0.1:4200/a 导航到< em> 127.0.0.1:4200/b 现在你在b。未来是 127.0.0.1:4200/a ,curr是b,因为未来意味着你将来会回来。

当shouldReuseRoute返回false时,将来!== curr。也就是说未来与curr不同,我们需要在未来重用未来,然后,未来将分离,存储和等待重用。相反,当它返回true时,没有做任何事情,因为未来与curr相同。想象当你进入a时,你想要去b,a是未来,b是curr.A和b是同样的事情,重用,分离,存储什么是必要的?

最后,您必须了解执行这五种方法的顺序。 例如:

navigate to a
shouldReuseRoute->return true->do nothing

a->b
shouldReuseRoute()->return false->shouldDetach()->return true->store a

then b->a
shouldReuseRoute()->return false->shouldDetach()->return true->store b->retrieve() return a ->attach() a.

小心,当b-&gt; a,在shouldReuseRoute()之后返回false时,这些方法严格按照上面的顺序排列。为了让你更容易理解这个过程,我故意写了。但是你还是按照上面的顺序去理解,这没有任何效果。

为了更好地理解,您应该看看这些示例。其中一个例子涉及延迟加载。

https://medium.com/@gerasimov.pk/how-to-reuse-rendered-component-in-angular-2-3-with-routereusestrategy-64628e1ca3eb

How to implement RouteReuseStrategy shouldDetach for specific routes in Angular 2

我的英语不好,我希望你能理解我说的话。