Angular 子路径改变时子路由不更新

Angular child route not updating when the subpath changes

根据 Angular“英雄之旅”教程修改我的工作,我试图了解子路由的工作原理。我有一个嵌入了 <router-outlet></router-outlet> 的 HeroesComponent。 HeroesComponent,通过'/heroes'到达,显示单个英雄的 link 列表,每个 routerLink 设置为 '/heroes/[id]',显示该英雄的 ID 而不是 '[ id]'--'/heroes/7',例如.

(我知道如何在不使用子路由的情况下将子组件直接添加到父组件。我在这里的目的是学习子路由的工作原理。对于直接子组件,我知道使用ngOnChanges,但是在在这种情况下,它不是正在更改的 @Input 组件 属性,它是路由器 属性。)

路由选择

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'heroes', component: HeroesComponent, runGuardsAndResolvers: 'always', children: [
    { path: ':id', component: HeroDetailComponent, runGuardsAndResolvers: 'always' }
  ] },
  { path: 'dashboard', component: DashboardComponent }
];

父 HeroesComponent 中的子路由出口

<section>
    <h2>All Heroes</h2>
    <div><a routerLink="/detail">Create a hero</a></div>
    <table class="table">
        <thead>
            <tr><th>Name</th><th>Location</th></tr>
        </thead>
        <tbody>
            <tr *ngFor="let hero of heroes">
                <th><a routerLink="/heroes/{{hero.id}}">{{hero.name}}</a></th>
                <td>{{hero.location}}</td>
                <td><a (click)="delete(hero.id)">delete</a></td>
            </tr>
        </tbody>
    </table>
</section>

<router-outlet></router-outlet>

子HeroDetailComponent中的关键代码

  ngOnInit(): void {
    let id: string;
// I'll explain this comment later.
//    this.route.paramMap.subscribe((paramMap) => id = paramMap.get('id'));
    id = this.route.snapshot.paramMap.get('id');
    if (id) {
      this.mode = 'update';
      this.heroService.getHero(+id).subscribe((hero) => {
        this.hero = hero
      });
    } else {
      this.mode = 'add';
      this.hero = { id: 0, name: '', location: '', cuisine: 0 }
    }
  }

导航到 /heroes 给我以下内容。 (我已经为 .NET CORE 教程设置了一家餐厅 API,因此我将其重新用作此 Angular 教程的数据源。)

浏览器地址栏显示“localhost:4200/heroes”。当我将光标悬停在“Masseria”上时,浏览器状态栏(如果重要的话,这是 Windows 10 上的 Chrome)显示为“http://localhost:4200/heroes/9” .单击 Masseria link,我得到:

到目前为止,一切顺利! 但是 ,当我点击 Takumi link 时,尽管浏览器地址字段的内容正确更改为“http://localhost:4200/heroes/13", 显示没有变化:我仍在查看 Masseria 的详细信息。

现在,如果我单击浏览器地址字段并按 Enter,然后 整个页面会刷新,显示餐厅列表和 Takumi 的详细信息。

我认为一些必要的更新通知没有发生。我做了一点研究。关于我在上面最后一段代码中注释掉的行,我认为使用

显式订阅路由器参数 :id 可能会有所帮助
this.route.paramMap.subscribe((paramMap) => id = paramMap.get('id'));

而不是从路由器快照中获取参数。这没有效果。

我还尝试将属性 runGuardsAndResolvers: 'always' 添加到我的路由数组中的父路径和子路径(上面的第一段代码),但这也没有效果。

阿克,我明白了。我在 OnInit 中订阅了路由器的 paramMap:

this.route.paramMap.subscribe((paramMap) => id = paramMap.get('id'));

我遗漏的部分是所有状态计算都需要在订阅回调中进行,而不仅仅是设置 ID 值。看:

  ngOnInit(): void {
    let id: string;
    this.route.paramMap.subscribe((paramMap) => {
      id = paramMap.get('id');
      if (id) {
        this.mode = 'update';
        this.heroService.getHero(+id).subscribe((hero) => {
          this.hero = hero
        });
      } else {
        this.mode = 'add';
        this.hero = { id: 0, name: '', location: '', cuisine: 0 }
      }
    }
  );

现在一切正常。