Angular2同一模板中的多路由器出口

是否有可能在同一模板中有多个路由器出口?

如果是,那么如何配置路由?

我用的是 angular2beta。

155450 次浏览

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'}

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 {}

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

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'
}
]
}

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 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>

This worked for me and pretty straight-forward and simple.

<div *ngIf="authenticated">
<ng-container *ngTemplateOutlet="template"></ng-container>
</div>


<div *ngIf="!authenticated">
<ng-container *ngTemplateOutlet="template"></ng-container>
</div>


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