Router-outlet 在 Routerlink 导航后没有更新
Router-outlet is not updating after Routerlink navigation
我正在创建一个带有导航菜单的简单 Angular 应用程序。每个菜单项都有一个 Routerlink
用于在页面之间导航。这是页面:
- 首页(
#/home
)
- 客户/信息(
#/customer/info
)
- 客户/详细信息(
#/customer/details
)
- 客户/详情/b0 (
#/customer/details/b0
)
- 客户/详情/b1 (
#/customer/details/b1
)
相关代码:
app.module.ts
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(
[
{
path: "",
redirectTo: "home",
pathMatch: "full"
},
{
path: "home",
component: HomeComponent
},
{
path: "customer",
component: CustomerComponent,
children: [
{
path: "",
redirectTo: "info",
pathMatch: "full"
},
{
path: "info",
component: CustomerInfoComponent,
},
{
path: "details",
component: CustomerDetailsComponent,
children: [
{
path: "",
redirectTo: "b0",
pathMatch: "full"
},
{
path: "b0",
component: CustomerDetailsBlock0Component
},
{
path: "b1",
component: CustomerDetailsBlock1Component
},
]
}
]
}
],
{useHash: true}
)
],
declarations: [ AppComponent, CustomerComponent, MenuComponent, HomeComponent, CustomerInfoComponent, CustomerDetailsComponent, CustomerDetailsBlock0Component, CustomerDetailsBlock1Component ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
客户-component.html
<p>This is customer #{{id}}</p>
<app-menu>
<router-outlet></router-outlet>
</app-menu>
客户详情-component.html
<p>This is customer details</p>
<router-outlet></router-outlet>
客户详细信息块0-component.html
<p>details block0</p>
客户详细信息块 1-component.html
<p>details block1</p>
菜单-component.html
<div>
<ul>
<li>
<a routerLink="">Home</a>
</li>
<li>
<a routerLink="../customer">Customer</a>
<ul>
<li>
<a routerLink="../customer/info">Info</a>
</li>
<li>
<a routerLink="../customer/details">Details</a>
<ul>
<li>
<a routerLink="../customer/details/b0">Block #0</a>
</li>
<li>
<a routerLink="../customer/details/b1">Block #1</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>------------- Content inside menu router-outlet -------------</p>
<router-outlet></router-outlet>
<p>--------------------------------------------------------------------</p>
</div>
导航工作正常:当我单击 link 时,激活的路线发生了变化,router-outlet
被更新并显示了预期的组件。
当路由为#/customer/details/b1
时刷新页面(或者直接点击,没有点击父菜单项),问题就来了:组件是好的,但是我的菜单被打破。如果我点击 link 去 #/customer/details/b0
路线改变了但是路由器插座没有更新,b1
组件仍然显示并且 b0
没有.
当我单击 URL 不是以 "customer/details" 开头的另一个菜单项时,此问题已修复,例如,如果我单击 "Info",则问题消失。
我想这是组件 customer-details
是同一个实例的问题,因此 Angular 重用它。但是为什么子组件没有改变?
我设法 "fix" 通过在每次调用路由器 shouldReuseRoute 函数时返回 false 来实现此行为:
// menu-component.ts
constructor(private router: Router) {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
但我不想每次都 destroy/create 我所有的组件。有什么解决办法吗?
这是 Stackblitz demo。要重现错误:
- 点击link"Block #1"
- 刷新 Stackblitz 输出 window
- 点击"Block #0" 或"Details" : 路由已更改但消息仍然是"details block1"
- 点击"Info"
- 重复步骤 1。 -> 现在问题已解决。
编辑: 我仍然遇到 Angular v6.1.3 的问题(我更新了 Stackblitz demo)。我尝试了@mast3rd3mon 提供的所有解决方案,但似乎无法解决问题。
看了你做的demo,需要去掉router链接的..
部分。 ../customer
变为 /customer
,../customer/info
变为 /customer/info
等
它可能只是演示,但请确保 app.component.html 文件看起来像 <router-outlet></router-outlet>
而不是 <router-outlet>
,因为标签需要有一个结束标签。
问题来自 MenuComponent
。您必须插入 <ng-content></ng-content>
而不是 <router-outlet></router-outlet>
,因为 <router-outler></router-outlet>
后面的组件在调用 MenuComponent
的组件中初始化(本例中为 CustomerComponent
)。
所以menu.component.html
中的代码应该是:
<p>------------- Content inside menu router-outlet -------------</p>
<ng-content></ng-content>
<p>--------------------------------------------------------------------</p>
使用路由参数':blockId'[=14=]将CustomerDetailsBlock0Component
、CustomerDetailsBlock1Component
合并到CustomerDetailsBlockComponent
CustomerDetailsBlockComponent{
blockId: number
constructor(private router Router){
this.router.events.subscribe(event=>{
if (event instanceof ActivationEnd && event.snapshot) {
let blockId = +event.snapshot.paramMap.get('blockId')
if (blockId) {
this.blockId = blockId
//update other angular bindings
}
}
})
}
}
我正在创建一个带有导航菜单的简单 Angular 应用程序。每个菜单项都有一个 Routerlink
用于在页面之间导航。这是页面:
- 首页(
#/home
) - 客户/信息(
#/customer/info
) - 客户/详细信息(
#/customer/details
) - 客户/详情/b0 (
#/customer/details/b0
) - 客户/详情/b1 (
#/customer/details/b1
)
相关代码:
app.module.ts
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(
[
{
path: "",
redirectTo: "home",
pathMatch: "full"
},
{
path: "home",
component: HomeComponent
},
{
path: "customer",
component: CustomerComponent,
children: [
{
path: "",
redirectTo: "info",
pathMatch: "full"
},
{
path: "info",
component: CustomerInfoComponent,
},
{
path: "details",
component: CustomerDetailsComponent,
children: [
{
path: "",
redirectTo: "b0",
pathMatch: "full"
},
{
path: "b0",
component: CustomerDetailsBlock0Component
},
{
path: "b1",
component: CustomerDetailsBlock1Component
},
]
}
]
}
],
{useHash: true}
)
],
declarations: [ AppComponent, CustomerComponent, MenuComponent, HomeComponent, CustomerInfoComponent, CustomerDetailsComponent, CustomerDetailsBlock0Component, CustomerDetailsBlock1Component ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
客户-component.html
<p>This is customer #{{id}}</p>
<app-menu>
<router-outlet></router-outlet>
</app-menu>
客户详情-component.html
<p>This is customer details</p>
<router-outlet></router-outlet>
客户详细信息块0-component.html
<p>details block0</p>
客户详细信息块 1-component.html
<p>details block1</p>
菜单-component.html
<div>
<ul>
<li>
<a routerLink="">Home</a>
</li>
<li>
<a routerLink="../customer">Customer</a>
<ul>
<li>
<a routerLink="../customer/info">Info</a>
</li>
<li>
<a routerLink="../customer/details">Details</a>
<ul>
<li>
<a routerLink="../customer/details/b0">Block #0</a>
</li>
<li>
<a routerLink="../customer/details/b1">Block #1</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>------------- Content inside menu router-outlet -------------</p>
<router-outlet></router-outlet>
<p>--------------------------------------------------------------------</p>
</div>
导航工作正常:当我单击 link 时,激活的路线发生了变化,router-outlet
被更新并显示了预期的组件。
当路由为#/customer/details/b1
时刷新页面(或者直接点击,没有点击父菜单项),问题就来了:组件是好的,但是我的菜单被打破。如果我点击 link 去 #/customer/details/b0
路线改变了但是路由器插座没有更新,b1
组件仍然显示并且 b0
没有.
当我单击 URL 不是以 "customer/details" 开头的另一个菜单项时,此问题已修复,例如,如果我单击 "Info",则问题消失。
我想这是组件 customer-details
是同一个实例的问题,因此 Angular 重用它。但是为什么子组件没有改变?
我设法 "fix" 通过在每次调用路由器 shouldReuseRoute 函数时返回 false 来实现此行为:
// menu-component.ts
constructor(private router: Router) {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
但我不想每次都 destroy/create 我所有的组件。有什么解决办法吗?
这是 Stackblitz demo。要重现错误:
- 点击link"Block #1"
- 刷新 Stackblitz 输出 window
- 点击"Block #0" 或"Details" : 路由已更改但消息仍然是"details block1"
- 点击"Info"
- 重复步骤 1。 -> 现在问题已解决。
编辑: 我仍然遇到 Angular v6.1.3 的问题(我更新了 Stackblitz demo)。我尝试了@mast3rd3mon 提供的所有解决方案,但似乎无法解决问题。
看了你做的demo,需要去掉router链接的..
部分。 ../customer
变为 /customer
,../customer/info
变为 /customer/info
等
它可能只是演示,但请确保 app.component.html 文件看起来像 <router-outlet></router-outlet>
而不是 <router-outlet>
,因为标签需要有一个结束标签。
问题来自 MenuComponent
。您必须插入 <ng-content></ng-content>
而不是 <router-outlet></router-outlet>
,因为 <router-outler></router-outlet>
后面的组件在调用 MenuComponent
的组件中初始化(本例中为 CustomerComponent
)。
所以menu.component.html
中的代码应该是:
<p>------------- Content inside menu router-outlet -------------</p>
<ng-content></ng-content>
<p>--------------------------------------------------------------------</p>
使用路由参数':blockId'[=14=]将CustomerDetailsBlock0Component
、CustomerDetailsBlock1Component
合并到CustomerDetailsBlockComponent
CustomerDetailsBlockComponent{
blockId: number
constructor(private router Router){
this.router.events.subscribe(event=>{
if (event instanceof ActivationEnd && event.snapshot) {
let blockId = +event.snapshot.paramMap.get('blockId')
if (blockId) {
this.blockId = blockId
//update other angular bindings
}
}
})
}
}