问题
I have an Angular2 application with one router outlet that displays different components depending on which link is clicked in a side menu.
The markup for the main component containing the <router-outlet>
looks like this
<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>
If I click the Demo link, the demo component is rendered, but if I then click the Home link, the home component is rendered above the demo component in DOM. Clicking them a few times will result with a DOM like this
<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>
The routes are defined as
export const router: Routes = [
{ path: 'demo', component: DemoComponent, canActivate: [AuthGuard] },
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] }
]
How come that the <router-outlet>
doesn't replace the component, but instead adds another "instance" of the component when switching between the routes?
回答1:
By using the method of elimination, I found out that the culprit of the issue was the BrowserAnimations
module in my app.module.ts
. By removing it from my imports
it the problem went away. I'll look into creating a Plunker to demonstrate it.
Update: This is described in this Github issue.
Update 2017-12-13: This has now been fixed with this PR, fix(animations): properly recover and cleanup DOM when CD failures occur.
回答2:
This happens also when component A is throwing an error, so when navigating to Component B, Component A could not be destroyed due to the error. This is a bug with Angular. Until they fix, find the cause of the error being thrown and fix it. Check your dev tools console.
回答3:
I had a very similar issue, also using Firebase.
See the components being appended to router outlet
However, I found that the issue was coming from an error within one of my components, not related to my routing. One of the components had a reference to a "FormsArray", which was not used and malformed. It threw errors in the devtools console, but I didn't think of checking there, since everything was compiling fine.
Not sure if that will help anybody.
回答4:
I was using NgZone inside the component and my routerLink was having the same issue, without any errors inside console.
Changed the routerLink to a (click) inside and called a function like this:
constructor(
(...)
private zone: NgZone,
(...)
) { }
goToPage() {
this.zone.run(() => this.router.navigate(['/page']));
}
回答5:
I had a similar issue , and the reason was that i used a directive that is not declared in component A and there was no error in compile or console. so when navigate to component B the router was appending the content.
To debug I commented out all the html markup in both components leaving only a h1 to see if the content was appending. with some tests i found the directive and by removing it, router back to normal again.
回答6:
I'm not sure if this matches your situation exactly, however I have had previous Components append to the DOM when trying to load a different route, and finally I figured that the use of Hash
was conflicting with addresses of the component,
export const AppRouting = RouterModule.forRoot(routes, { useHash: false });
This fixed all my problems with unwanted appended components
来源:https://stackoverflow.com/questions/45622453/angular2-router-appends-component-instead-of-replacing-it