路由
路由是 Angular 应用程序的核心,它加载与所请求路由相关联的组件,以及获取特定路由的相关数据。这允许我们通过控制不同的路由,获取不同的数据,从而渲染不同的页面。
一、路由的使用
- 当一个路由链接被触发时会去路由配置中匹配;
- 最终找到对应组件;
- 在路由出口显示出来;
1.1 base 元素
大多数带路由的应用都要在index.html的 <head> 标签下先添加一个 <base> 元素,来告诉路由器该如何合成导航用的 URL。
| <!DOCTYPE html>
<html lang="en">
<head>
<base href="/"> <!-- Set the base href -->
</head>
<body>
<app-root></app-root>
</body>
</html>
|
1.2 导入路由库
| import { RouterModule, Routes } from '@angular/router';
|
1.3 路由配置数组
路由数组 appRoutes 描述如何进行导航,把它传给 RouterModule.forRoot 方法并传给本模块的 imports 数组就可以配置路由器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | const appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent },
{ path: 'hero/:id', component: HeroDetailComponent },
{
path: 'heroes',
component: HeroListComponent,
data: { title: 'Heroes List' }
},
{ path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } // <-- debugging purposes only
)
]
})
export class AppModule { }
|
| 属性 |
用途 |
| RouterModule.forRoot() |
方法用于在主模块中定义主要的路由信息。 |
| RouterModule.forChild() |
RouterModule.forChild() 与 Router.forRoot() 方法类似,但它只能应用在特性模块中 |
| path |
定义路由的匹配路径 |
| component |
用于定义路由匹配时需要加载的组件 |
| 第二个路由中的:id |
是路由参数,而不是 URL 中实际的部分 |
| 第三个路由中的 data |
用来存放于每个具体路由有关的任意信息。该数据可以被任何一个激活路由访问。 |
最后一个路由中的 ** 路径 |
当所请求的 URL 不匹配前面定义的路由表中的任何路径时,路由器就会选择此路由。 |
1.4 路由出口
| <router-outlet></router-outlet>
<!-- Routed views go here -->
|
1.5 路由器链接
a 标签上的 RouterLink 指令让路由器得以控制这个 a 元素。
| <h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
|
二、其他
2.1 重定向路由
| const appRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
{ path: '', redirectTo: '/heroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
];
|
使用redirectTo关键字, 当访问‘ ’时,会重定向到 ‘heroes’ 最终找到 HeroListComponent组件
pathMatch: 'full' :表示完全匹配,
pathMatch 的另一个可能的值是 'prefix',它会告诉路由器:当剩下的URL 以这个跳转路由中的 prefix 值开头。
2.2路由参数传递与获取
2.2.1 路由参数传递
路由配置:
| { path: 'hero/:id', component: HeroDetailComponent }
|
路由传参:
| <a routerLink="['/hero', hero.id]" >Heroes</a>
|
2.2.2 ActivatedRoute获取参数
从路由器(router)包中导入 Router、ActivatedRoute 和 Params 类。
| import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { switchMap } from 'rxjs/operators';
|
通常,你会直接写一个构造函数,让 Angular 把组件所需的服务注入进来,自动定义同名的私有变量,并把它们存进去。
| constructor(
private route: ActivatedRoute,
private router: Router,
private service: HeroService
) {}
|
然后,在 ngOnInit 方法中,你用 ActivatedRoute 服务来接收路由的参数
switchMap 操作符: 会取消以前未完成的在途请求,重新获取新的数据;
| ngOnInit() {
this.hero$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
);
}
|
Snapshot(快照):组件的实例永远不会被复用,那就可以使用快照;
| ngOnInit() {
let id = this.route.snapshot.paramMap.get('id');
this.hero$ = this.service.getHero(id);
}
|
2.3导航
路由的 navigate 方法同样接受一个单条目的链接参数数组,你也可以把它绑定到 [routerLink] 指令上。 它保存着到 HeroListComponent 组件的路径:
| this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);
|
2.4子路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | const crisisCenterRoutes: Routes = [
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
{
path: '',
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
];
|
2.5 惰性加载路由
AppModule 在应用启动时就被加载了,它是立即加载的。
惰性加载 : 只有当用户点击某个链接时才会加载。
loadChildren 属性
| {
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule',
},
|