Angular2 路由器附加组件而不是替换它
Angular2 router appends component instead of replacing it
我有一个 Angular2 应用程序,它有一个路由器插座,根据在侧面菜单中单击 link 显示不同的组件。
包含 <router-outlet>
的主要组件的标记如下所示
<div *ngIf="authenticated == false">
<app-login></app-login>
</div>
<div *ngIf="authenticated">
<div class="page home-page">
<header class="header">
<app-navbar></app-navbar>
</header>
<div class="page-content d-flex align-items-stretch">
<div class="sidebar-container">
<app-sidebar-menu></app-sidebar-menu>
</div>
<div class="content-inner">
<app-page-header></app-page-header>
<div id="sub-content">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
</div>
</div>
</div>
如果我单击 Demo link,将呈现演示组件,但如果我随后单击 Home link,home组件渲染在DOM的demo组件之上。单击它们几次将得到 DOM 这样的
<div _ngcontent-c0="" id="sub-content">
<router-outlet _ngcontent-c0=""></router-outlet>
<app-home _nghost-c6="">...</app-home>
<app-demo _nghost-c7="">...</app-demo>
<app-home _nghost-c6="">...</app-home> <!-- Why so many here? Should be just either one <app-home> or <app-demo> -->
<app-demo _nghost-c7="">...</app-demo>
<app-home _nghost-c6="">...</app-home>
<app-demo _nghost-c7="">...</app-demo>
<app-footer _ngcontent-c0="" _nghost-c5="">...</app-footer>
</div>
路线定义为
export const router: Routes = [
{ path: 'demo', component: DemoComponent, canActivate: [AuthGuard] },
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] }
]
为什么<router-outlet>
不替换组件,而是在切换路由时添加另一个"instance"组件?
通过排除法,我发现问题的罪魁祸首是我app.module.ts
中的BrowserAnimations
模块。通过从我的 imports
中删除它,问题就消失了。我将研究创建一个 Plunker 来演示它。
更新:
Github issue.
中对此进行了描述
2017-12-13更新:
现在这个 PR 已经解决了,fix(animations): properly recover and cleanup DOM when CD failures occur.
我有一个非常相似的问题,也是使用 Firebase。
See the components being appended to router outlet
但是,我发现问题出在我的一个组件中,与我的路由无关。其中一个组件引用了 "FormsArray",它未被使用且格式错误。它在 devtools 控制台中抛出错误,但我没有想到在那里检查,因为一切都编译正常。
不确定这是否对任何人有帮助。
当 组件 A 抛出错误时也会发生这种情况,因此当导航到组件 B 时,组件 A 由于错误而无法销毁。这是 Angular 的错误。在他们修复之前,找到引发错误的原因并修复它。检查您的开发工具控制台。
我不确定这是否完全符合您的情况,但是我在尝试加载不同的路由时将以前的组件附加到 DOM,最后我发现使用 Hash
与组件地址冲突,
export const AppRouting = RouterModule.forRoot(routes, { useHash: false });
这解决了我所有关于不需要的附加组件的问题
我在组件内部使用了 NgZone,我的 routerLink 遇到了同样的问题,但控制台内部没有任何错误。
将 routerLink 更改为(单击)内部并调用如下函数:
constructor(
(...)
private zone: NgZone,
(...)
) { }
goToPage() {
this.zone.run(() => this.router.navigate(['/page']));
}
我遇到了类似的问题,原因是我使用了一个未在组件 A 中声明的指令,并且在编译或控制台中没有错误。
所以当导航到组件 B 时,路由器正在附加内容。
为了调试,我注释掉了两个组件中的所有 html 标记,只留下一个 h1 来查看内容是否附加。通过一些测试,我找到了指令并通过删除它,路由器再次恢复正常。
我有一个 Angular2 应用程序,它有一个路由器插座,根据在侧面菜单中单击 link 显示不同的组件。
包含 <router-outlet>
的主要组件的标记如下所示
<div *ngIf="authenticated == false">
<app-login></app-login>
</div>
<div *ngIf="authenticated">
<div class="page home-page">
<header class="header">
<app-navbar></app-navbar>
</header>
<div class="page-content d-flex align-items-stretch">
<div class="sidebar-container">
<app-sidebar-menu></app-sidebar-menu>
</div>
<div class="content-inner">
<app-page-header></app-page-header>
<div id="sub-content">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
</div>
</div>
</div>
如果我单击 Demo link,将呈现演示组件,但如果我随后单击 Home link,home组件渲染在DOM的demo组件之上。单击它们几次将得到 DOM 这样的
<div _ngcontent-c0="" id="sub-content">
<router-outlet _ngcontent-c0=""></router-outlet>
<app-home _nghost-c6="">...</app-home>
<app-demo _nghost-c7="">...</app-demo>
<app-home _nghost-c6="">...</app-home> <!-- Why so many here? Should be just either one <app-home> or <app-demo> -->
<app-demo _nghost-c7="">...</app-demo>
<app-home _nghost-c6="">...</app-home>
<app-demo _nghost-c7="">...</app-demo>
<app-footer _ngcontent-c0="" _nghost-c5="">...</app-footer>
</div>
路线定义为
export const router: Routes = [
{ path: 'demo', component: DemoComponent, canActivate: [AuthGuard] },
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] }
]
为什么<router-outlet>
不替换组件,而是在切换路由时添加另一个"instance"组件?
通过排除法,我发现问题的罪魁祸首是我app.module.ts
中的BrowserAnimations
模块。通过从我的 imports
中删除它,问题就消失了。我将研究创建一个 Plunker 来演示它。
更新: Github issue.
中对此进行了描述2017-12-13更新: 现在这个 PR 已经解决了,fix(animations): properly recover and cleanup DOM when CD failures occur.
我有一个非常相似的问题,也是使用 Firebase。
See the components being appended to router outlet
但是,我发现问题出在我的一个组件中,与我的路由无关。其中一个组件引用了 "FormsArray",它未被使用且格式错误。它在 devtools 控制台中抛出错误,但我没有想到在那里检查,因为一切都编译正常。
不确定这是否对任何人有帮助。
当 组件 A 抛出错误时也会发生这种情况,因此当导航到组件 B 时,组件 A 由于错误而无法销毁。这是 Angular 的错误。在他们修复之前,找到引发错误的原因并修复它。检查您的开发工具控制台。
我不确定这是否完全符合您的情况,但是我在尝试加载不同的路由时将以前的组件附加到 DOM,最后我发现使用 Hash
与组件地址冲突,
export const AppRouting = RouterModule.forRoot(routes, { useHash: false });
这解决了我所有关于不需要的附加组件的问题
我在组件内部使用了 NgZone,我的 routerLink 遇到了同样的问题,但控制台内部没有任何错误。
将 routerLink 更改为(单击)内部并调用如下函数:
constructor(
(...)
private zone: NgZone,
(...)
) { }
goToPage() {
this.zone.run(() => this.router.navigate(['/page']));
}
我遇到了类似的问题,原因是我使用了一个未在组件 A 中声明的指令,并且在编译或控制台中没有错误。 所以当导航到组件 B 时,路由器正在附加内容。
为了调试,我注释掉了两个组件中的所有 html 标记,只留下一个 h1 来查看内容是否附加。通过一些测试,我找到了指令并通过删除它,路由器再次恢复正常。