angular 11.2.9 routerLink 不会重新初始化相同的组件
angular 11.2.9 routerLink doesn't re-initialise same component
我做错了什么,但找不到解决这个问题的确切方法。
我有一个带有视图组件的路由器 A
:
const routes: Routes = [
{ path: '', redirectTo: '/list', pathMatch: 'full' },
{ path: 'list', component: ListComponent },
{ path: 'a/:id/:version', component: AComponent, resolve: { a: DataResolver}, runGuardsAndResolvers: 'always' }
];
一切正常 - 我正在导航到 A
组件 /a/1/v1
- 一切都已完美初始化。
问题:组件正在加载视图内容的其他版本的功能,我希望如果我只是在 A
组件视图中的某处单击 <a routerLink="/a/1/v2">load version 2</a>
,该视图是重生了。
实际情况是
- url 在浏览器中已更改
- 调用与路由关联的数据提供程序并获取与新 url 关联的新数据
- 构造函数或
ngOnInit
未被调用
有趣的是,如果我配置 /b/..
并将其分配给路由器配置中相同的 A
组件,从 /a/1/v1
导航到 [=22 后,一切都按预期工作=].
const routes: Routes = [
{ path: '', redirectTo: '/list', pathMatch: 'full' },
{ path: 'list', component: ListComponent },
{ path: 'a/:id/:version', component: AComponent, resolve: { a: DataResolver}, runGuardsAndResolvers: 'always' },
{ path: 'b/:id/:version', component: AComponent, resolve: { a: DataResolver}, runGuardsAndResolvers: 'always' },
];
我有点迷茫。感谢您的帮助。
在导航到您的组件时未调用构造函数和 ngOnInit
的原因源于 Angular 的默认值 RouteReuseStrategy。
This base route reuse strategy only reuses routes when the matched router configs are identical. This prevents components from being destroyed and recreated when just the fragment or query parameters change (that is, the existing component is reused).
换句话说,因为只有 URL 的片段发生了变化,/a/1/v1
-> /a/1/v2
,Angular 试图聪明地重用组件。这可以防止构造函数和 ngOnInit
再次被调用。 (我知道,真气,对吧?)
我能想到几个解决方案。
- 监听路由参数何时更改并处理回调中的任何初始化逻辑。这意味着您需要订阅可观察到的路由参数,并将最初在
ngOnInit
中的逻辑移动到订阅中。
class AComponent implements OnInit {
constructor(private _route: ActivatedRoute) {}
ngOnInit(): void {
this._route.params.subscribe(newParams => {
// handle any initialization logic here.
});
}
}
- 您可以用自己的 Angular 默认 RouteReuseStrategy 覆盖,以防止 Angular 重复使用路由组件。这是我们最终采用的方法。很容易忘记这个 Angular “功能”。您可以像这样覆盖默认路由重用策略。
export class MyCustomRouteReuseStrategy implements RouteReuseStrategy {
// Never reuse a component!
shouldReuseRoute(): boolean {
return false;
}
// Implement the other default methods. Keep same functionality.
shouldDetach(): boolean { return false; }
store(): void {}
shouldAttach(): boolean { return false; }
retrieve(): DetachedRouteHandle | null { return null; }
}
// app.module.ts
@NgModule({
providers: [
{ provide: RouteReuseStrategy, useClass: MyCustomRouteReuseStrategy },
]
我做错了什么,但找不到解决这个问题的确切方法。
我有一个带有视图组件的路由器 A
:
const routes: Routes = [
{ path: '', redirectTo: '/list', pathMatch: 'full' },
{ path: 'list', component: ListComponent },
{ path: 'a/:id/:version', component: AComponent, resolve: { a: DataResolver}, runGuardsAndResolvers: 'always' }
];
一切正常 - 我正在导航到 A
组件 /a/1/v1
- 一切都已完美初始化。
问题:组件正在加载视图内容的其他版本的功能,我希望如果我只是在 A
组件视图中的某处单击 <a routerLink="/a/1/v2">load version 2</a>
,该视图是重生了。
实际情况是
- url 在浏览器中已更改
- 调用与路由关联的数据提供程序并获取与新 url 关联的新数据
- 构造函数或
ngOnInit
未被调用
有趣的是,如果我配置 /b/..
并将其分配给路由器配置中相同的 A
组件,从 /a/1/v1
导航到 [=22 后,一切都按预期工作=].
const routes: Routes = [
{ path: '', redirectTo: '/list', pathMatch: 'full' },
{ path: 'list', component: ListComponent },
{ path: 'a/:id/:version', component: AComponent, resolve: { a: DataResolver}, runGuardsAndResolvers: 'always' },
{ path: 'b/:id/:version', component: AComponent, resolve: { a: DataResolver}, runGuardsAndResolvers: 'always' },
];
我有点迷茫。感谢您的帮助。
在导航到您的组件时未调用构造函数和 ngOnInit
的原因源于 Angular 的默认值 RouteReuseStrategy。
This base route reuse strategy only reuses routes when the matched router configs are identical. This prevents components from being destroyed and recreated when just the fragment or query parameters change (that is, the existing component is reused).
换句话说,因为只有 URL 的片段发生了变化,/a/1/v1
-> /a/1/v2
,Angular 试图聪明地重用组件。这可以防止构造函数和 ngOnInit
再次被调用。 (我知道,真气,对吧?)
我能想到几个解决方案。
- 监听路由参数何时更改并处理回调中的任何初始化逻辑。这意味着您需要订阅可观察到的路由参数,并将最初在
ngOnInit
中的逻辑移动到订阅中。
class AComponent implements OnInit {
constructor(private _route: ActivatedRoute) {}
ngOnInit(): void {
this._route.params.subscribe(newParams => {
// handle any initialization logic here.
});
}
}
- 您可以用自己的 Angular 默认 RouteReuseStrategy 覆盖,以防止 Angular 重复使用路由组件。这是我们最终采用的方法。很容易忘记这个 Angular “功能”。您可以像这样覆盖默认路由重用策略。
export class MyCustomRouteReuseStrategy implements RouteReuseStrategy {
// Never reuse a component!
shouldReuseRoute(): boolean {
return false;
}
// Implement the other default methods. Keep same functionality.
shouldDetach(): boolean { return false; }
store(): void {}
shouldAttach(): boolean { return false; }
retrieve(): DetachedRouteHandle | null { return null; }
}
// app.module.ts
@NgModule({
providers: [
{ provide: RouteReuseStrategy, useClass: MyCustomRouteReuseStrategy },
]