子模块中的RouteReuseStrategy

Jar*_*ers 5 routing angular

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

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

路线:

const acnpRoutes: Routes = [
  {
    path: '',
    component: AddCustomerNaturalPersonComponent,
    children: [
      {
        path: 'stepOne',
        component: ACNPStepOneComponent
      },
      {
        path: 'stepTwo',
        component: ACNPStepTwoComponent
      },
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

和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)
  }
}
Run Code Online (Sandbox Code Playgroud)

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

yez*_*322 7

TL;DR提供您RouteReuseStrategy的主模块而不是子模块(app.module.ts默认情况下)。然后,分配各路线keyroute.data区分你的路由。


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

..., {    // in app.route.ts
          path: 'apimarket',
          canActivate: [DeveloperResolve],
          loadChildren: './apimarket/apimarket.module#ApiMarketModule'
}
Run Code Online (Sandbox Code Playgroud)

如果我RouteReuseStrategy在子模块中提供我的定制ApiMarketModuleRouteReuseStrategy则永远不会构建。

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

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

export const apimarketRoutes: Routes = [
    {
        path: '',
        component: ApiMarketComponent,
        data: {
            shouldReuse: true,
            key: 'apimarketroot'
        }
    },
    {
        path: ':id',
        component: ContentPageComponent,
    }
];
Run Code Online (Sandbox Code Playgroud)

这是我的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'];
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这太棒了,必须是一个可以接受的答案!今天它仍然与“Angular 12.x”相关。在我从这个答案中了解到“关键”部分之前,我的实现并未按预期工作。添加“密钥”后,它就可以完美运行。在可能的版本发布之后,Angular 文档仍然很差。我希望尽快提交 PR! (2认同)

小智 3

首先,您必须了解什么是futurecurr 。例如:当您从127.0.0.1:4200/a导航 到127.0.0.1:4200/b时,现在您位于 b 中。未来是 127.0.0.1:4200/a,curr 是 b\xef\xbc\x8c 因为 future 意味着你将来会回来。

\n\n

当 shouldReuseRoute 返回 false 时,future !== curr。也就是说future和curr不同,我们需要在future中重用future,那么future就会被分离,存储并等待被重用。相反,当它返回 true 时,什么也不做,因为 future 与 curr 相同。想象一下,当你在 a 中,你想去 b,a 是 future,b 是 curr。A 和 b同样的东西,有什么必要重用、分离、存储呢?

\n\n

最后,你要了解这五个方法的执行顺序。\neg\xef\xbc\x9a

\n\n
navigate to a\nshouldReuseRoute->return true->do nothing\n\na->b\nshouldReuseRoute()->return false->shouldDetach()->return true->store a\n\nthen b->a\nshouldReuseRoute()->return false->shouldDetach()->return true->store b->retrieve() return a ->attach() a.\n
Run Code Online (Sandbox Code Playgroud)\n\n

注意\xef\xbc\x8c当b->a时,shouldReuseRoute()返回false后,这些方法并不严格按照上面的顺序。为了让你更容易理解这个过程,我特意这么写的。但是你还是按照上面的顺序去理解,这没有任何影响。

\n\n

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

\n\n

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

\n\n

如何在 Angular 2 中为特定路由实现 RouteReuseStrategy shouldDetach

\n\n

我的英语不好,希望你能明白我说的。

\n