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 }
}
}
);
现在一切正常。
根据 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 }
}
}
);
现在一切正常。