官网原文 《用命名出口(outlet)显示多重路由》
建议本篇文章之前先阅读《angular2/4 路由参数详解》
文章目录
当用户点击“Contact
”按钮时,你要在一个弹出框中显示一条消息。
即使在应用中的不同页面之间切换,这个弹出框也应该始终保持打开状态,直到用户发送了消息或者手动取消。 显然,你不能把这个弹出框跟其它放到页面放到同一个路由出口中。
简单来说,我希望页面的某个位置显示一个消息提示框,这个框要一直存在页面上,不能在页面发生跳转的时候消失。
迄今为止,你只定义过单路由出口,并且在其中嵌套了子路由
以便对路由分组。 在每个模板中,路由器只能支持一个无名主路由出口。
我们在《angular2/4 路由参数详解》中有个
嵌套子路由例子
,setttings主页面加载子页面 password和profile
模板还可以有多个命名的路由出口。 每个命名出口都自己有一组带组件的路由。 多重出口可以在同一时间根据不同的路由来显示不同的内容
。
详细步骤
导航菜单
<ul>
<li>
<a routerLink='settings'>
settings</a>
</li>
<li>
<a routerLink='/home'>
Home</a>
</li>
</ul>
需要注意:我们此时导航中的链接是routerLink形式,如果是href,
popup:compose
会失效
app.component.html
在 AppComponent
中添加一个名叫“popup
”的出口,就在无名出口的下方。
<div>
<div class="sidebar" >
<!--导航->
<app-navigator></app-navigator>
</div>
<div class=" body-content " >
<!--正文->
<div>
<!--可以触发popup的链接->
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
<hr>
<!--第一层路由,没有名称->
<router-outlet></router-outlet>
<hr>
<!--第二层路由->
<router-outlet name="popup"></router-outlet>
</div>
</div>
</div>
主要新增下面的代码:
<router-outlet name="popup"></router-outlet>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
compose-message.component.css
:host {
position: relative; bottom: 10%;
}
compose.message.component.ts
import { Component, HostBinding } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-compose-message',
templateUrl: './compose-message.component.html',
styleUrls: ['./compose-message.component.css']
})
export class ComposeMessageComponent {
details: string;
message: string;
sending = false;
constructor(private router: Router) { }
send() {
this.sending = true;
this.details = 'Sending Message...';
setTimeout(() => {
this.sending = false;
this.closePopup();
}, 1000);
}
cancel() {
this.closePopup();
}
closePopup() {
// Providing a `null` value to the named outlet
// clears the contents of the named outlet
this.router.navigate([{ outlets: { popup: null } }]);
}
}
compose-message.component.html
<h3>Contact Crisis Center</h3>
<div *ngIf="details">
{{ details }}
</div>
<div>
<div>
<label>Message: </label>
</div>
<div>
<textarea [(ngModel)]="message" rows="10" cols="35" [disabled]="sending"></textarea>
</div>
</div>
<p *ngIf="!sending">
<button (click)="send()">Send</button>
<button (click)="cancel()">Cancel</button>
</p>
app-routing.module.ts
新增/compose
配置
export const ROUTES: Routes = [
{
path: 'settings',
component: SettingsComponent,
children: [
{ path: 'profile', component: ProfileSettingsComponent },
{ path: 'password', component: PasswordSettingsComponent }
]
},
{
path: 'compose',
component: ComposeMessageComponent,
outlet: 'popup'
},
{
path: 'home',
component: HomeMessageComponent
}
];
效果
1.首先我们在浏览器中输入http://localhost:4200/settings
页面与《angular2/4 路由参数详解》相比,多个一个Contact链接和2个分隔线。
此时,仅加载settings父页面
2.我们触发下Contact链接
此时url变为http://localhost:4200/settings(popup:compose)
多了(popup:compose)
此时,在第二分隔线下多个一个ComposeMessageComponent
3.通过链接触发profile子页面
此时通过
routerLink
实现跳转,如果是href,会刷新页面,丢失popup:compose
如果是通过按钮跳转,底层需要区分navigate和navigateByUrl,navigate保留popup:compose, navigateByUrl会丢失popup:compose
此时url 为 http://localhost:4200/settings/profile(popup:compose)
?name=lisi
多了(popup:compose)
,并且
ComposeMessageComponent
仍然存在,并且子页面加载成功。
4.切换至Home页面
此时url 为 http://localhost:4200/tasklist(popup:compose)
多了(popup:compose)
,并且
ComposeMessageComponent
仍然存在
总结一下:
- 通过
routerLink
实现跳转,保留popup:compose
,如果是href,会刷新页面,丢失popup:compose
- 如果是通过按钮跳转,底层需要区分
navigate
和navigateByUrl
,navigate
保留popup:compose
,navigateByUrl
会丢失popup:compose