【问题标题】:angular 11.2.9 routerLink doesn't re-initialise same component角度 11.2.9 routerLink 不会重新初始化相同的组件
【发布时间】:2021-05-19 10:36:44
【问题描述】:

我做错了,但找不到此问题的确切解决方案。

我有一个带有视图组件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 关联的新数据
  • 没有调用构造函数或ngOnInit

有趣的是,如果我配置 /b/.. 并将其分配给路由器配置中的相同 A 组件,则在从 /a/1/v1 导航到 /b/1/v2 后一切都会按预期工作。

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' },
];

我有点失落。感谢您的帮助。

【问题讨论】:

    标签: angular angular-ui-router


    【解决方案1】:

    在导航到您的组件时未调用构造函数和ngOnInit 的原因源于Angular 的默认RouteReuseStrategy

    此基本路由重用策略仅在匹配的路由器配置相同时重用路由。这可以防止组件在仅片段或查询参数更改时被销毁和重新创建(即重用现有组件)。

    换句话说,因为只有 URL 的片段发生了变化,/a/1/v1 -> /a/1/v2,Angular 试图变得聪明并重用组件。这可以防止再次调用构造函数和ngOnInit。 (我知道,真气,对吧?)

    我能想到几个解决方案。

    1. 监听路由参数何时更改并处理回调中的任何初始化逻辑。这意味着您需要订阅可观察的路由参数,并将最初在 ngOnInit 中的逻辑移动到订阅中。
    class AComponent implements OnInit {
        constructor(private _route: ActivatedRoute) {}
        
        ngOnInit(): void {
            this._route.params.subscribe(newParams => {
                 // handle any initialization logic here.
            }); 
        }
    
    }
    
    1. 您可以使用自己的覆盖 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 },
      ]
    

    【讨论】:

    • 谢谢!奇怪的是它没有在搜索中弹出。我正在搜索路由器本身的配置。
    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 2017-05-11
    • 2020-01-14
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    相关资源
    最近更新 更多