Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 router appends component instead of replacing it

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?

like image 846
Daniel B Avatar asked Aug 10 '17 19:08

Daniel B


People also ask

Is it possible to have a multiple router outlet in the same template?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows. Advantage of below approach is thats you can avoid dirty looking URL with it. eg: /home(aux:login) etc.

What module Do you need to add for using Angular router?

Import RouterModule from @angular/router link Routing lets you display specific views of your application depending on the URL path. To add this functionality to your sample application, you need to update the app.module.ts file to use the module, RouterModule . You import this module from @angular/router .

How do you add a routing to a component?

Run ng generate to create the application routing module. Puts the file in src/app instead of its own directory. Tells ng generate to register it in the imports array of the AppModule . First, the app-routing.module.ts file imports RouterModule and Routes so the application can have routing capability.

Can we use two router outlet in Angular?

Angular Router supports multiple outlets in the same application. A component has one associated primary route and can have auxiliary routes. Auxiliary routes enable developers to navigate multiple routes at the same time.


1 Answers

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.

like image 99
Daniel B Avatar answered Sep 21 '22 23:09

Daniel B