[angular] Angular2 multiple router-outlet in the same template

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

If yes then how to configure the routes?

I am using angular2 beta.

This question is related to angular angular2-routing angular2-template

The answer is


There seems to be another (rather hacky) way to reuse the router-outlet in one template. This answer is intendend for informational purposes only and the techniques used here should probably not be used in production.

https://stackblitz.com/edit/router-outlet-twice-with-events

The router-outlet is wrapped by an ng-template. The template is updated by listening to events of the router. On every event the template is swapped and re-swapped with an empty placeholder. Without this "swapping" the template would not be updated.

This most definetly is not a recommended approach though, since the whole swapping of two templates seems a bit hacky.

in the controller:

  ngOnInit() {
    this.router.events.subscribe((routerEvent: Event) => {
      console.log(routerEvent);
      this.myTemplateRef = this.trigger;
      setTimeout(() => {
        this.myTemplateRef = this.template;
      }, 0);
    });
  }

in the template:

<div class="would-be-visible-on-mobile-only">
  This would be the mobile-layout with a router-outlet (inside a template): 
  <br>
  <ng-container *ngTemplateOutlet="myTemplateRef"></ng-container>
</div>

<hr>

<div class="would-be-visible-on-desktop-only">
  This would be the desktop-layout with a router-outlet (inside a template): 
  <br>
  <ng-container *ngTemplateOutlet="myTemplateRef"></ng-container>
</div>

<ng-template #template>
    <br>
    This is my counter: {{counter}}
    inside the template, the router-outlet should follow
    <router-outlet>
    </router-outlet>
</ng-template>

<ng-template #trigger>
  template to trigger changes...
</ng-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.

Assuming on load you are bootstraping appComponent.

app.component.html

<div class="layout">
    <div class="page-header">
        //first outlet to load required component
        <router-outlet name='child1'></router-outlet>
    </div>
    <div class="content">
        //second outlet to load required component
        <router-outlet name='child2'></router-outlet>
    </div>
</div>

Add following to your router.

{
    path: 'home',  // you can keep it empty if you do not want /home
    component: 'appComponent',
    children: [
        {
            path: '',
            component: childOneComponent,
            outlet: 'child1'
        },
        {
            path: '',
            component: childTwoComponent,
            outlet: 'child2'
        }
    ]
}

Now when /home is loaded appComponent will get load with allocated template, then angular router will check the route and load the children component in specified router outlet on the basis of name.

Like above you can configure your router to have multiple router-outlet in same route.


<a [routerLink]="[{ outlets: { list:['streams'], details:['parties'] } }]">Link</a>

<div id="list">
    <router-outlet name="list"></router-outlet>
</div>
<div id="details">
    <router-outlet name="details"></router-outlet>
</div>

`

 {
    path: 'admin',
    component: AdminLayoutComponent,
    children:[
      {
        path: '',
        component: AdminStreamsComponent, 
        outlet:'list'
      },
      {
        path: 'stream/:id',
        component: AdminStreamComponent,
        outlet:'details'
      }
    ]
  }

You can not use multiple router outlets in the same template with ngIf condition. But you can use it in the way shown below:

<div *ngIf="loading">
  <span>loading true</span>
  <ng-container *ngTemplateOutlet="template"></ng-container>
</div>

<div *ngIf="!loading">
  <span>loading false</span>
  <ng-container *ngTemplateOutlet="template"></ng-container>
  </div>

  <ng-template #template>
    <router-outlet> </router-outlet>
  </ng-template>

yes you can, but you need to use aux routing. you will need to give a name to your router-outlet:

<router-outlet name="auxPathName"></router-outlet>

and setup your route config:

@RouteConfig([
  {path:'/', name: 'RetularPath', component: OneComponent, useAsDefault: true},
  {aux:'/auxRoute', name: 'AuxPath', component: SecondComponent}
])

Check out this example, and also this video.


Update for RC.5 Aux routes has changed a bit: in your router outlet use a name:

<router-outlet name="aux">

In your router config:

{path: '/auxRouter', component: secondComponentComponent, outlet: 'aux'}

Aux routes syntax has changed with the new RC.3 router.

There are some known issues with aux routes but basic support is available.

You can define routes to show components in a named <router-outlet>

Route config

{path: 'chat', component: ChatCmp, outlet: 'aux'}

Named router outlet

<router-outlet name="aux">

Navigate aux routes

this._router.navigateByUrl("/crisis-center(aux:chat;open=true)");

It seems navigating aux routes from routerLink is not yet supported

<a [routerLink]="'/team/3(aux:/chat;open=true)'">Test</a>

<a [routerLink]="['/team/3', {outlets: {aux: 'chat'}}]">c</a>

Not tried myself yet

See also Angular2 router in one component

RC.5 routerLink DSL (same as createUrlTree parameter) https://angular.io/docs/ts/latest/api/router/index/Router-class.html#!#createUrlTree-anchor


Yes you can as said by @tomer above. i want to add some point to @tomer answer.

  • firstly you need to provide name to the router-outlet where you want to load the second routing view in your view. (aux routing angular2.)
  • In angular2 routing few important points are here.

    • path or aux (requires exactly one of these to give the path you have to show as the url).
    • component, loader, redirectTo (requires exactly one of these, which component you want to load on routing)
    • name or as (optional) (requires exactly one of these, the name which specify at the time of routerLink)
    • data (optional, whatever you want to send with the routing that you have to get using routerParams at the receiver end.)

for more info read out here and here.

import {RouteConfig, AuxRoute} from 'angular2/router';
@RouteConfig([
  new AuxRoute({path: '/home', component: HomeCmp})
])
class MyApp {}

Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to angular2-routing

'router-outlet' is not a known element How to reload page the page with pagination in Angular 2? Error: Cannot match any routes. URL Segment: - Angular 2 Can't bind to 'routerLink' since it isn't a known property Passing data into "router-outlet" child components How to determine previous page URL in Angular? How to get parameter on Angular2 route in Angular way? Angular 2 Scroll to top on Route Change Angular routerLink does not navigate to the corresponding component Angular 2 router.navigate

Examples related to angular2-template

Please add a @Pipe/@Directive/@Component annotation. Error How to truncate text in Angular2? What is let-* in Angular 2 templates? angular2: Error: TypeError: Cannot read property '...' of undefined Can't bind to 'ngForOf' since it isn't a known property of 'tr' (final release) Angular2: Cannot read property 'name' of undefined How to prevent Browser cache on Angular 2 site? Angular 2 Scroll to top on Route Change <ng-container> vs <template> Angular 2: Can't bind to 'ngModel' since it isn't a known property of 'input'