路由

路由是 Angular 应用程序的核心,它加载与所请求路由相关联的组件,以及获取特定路由的相关数据。这允许我们通过控制不同的路由,获取不同的数据,从而渲染不同的页面。

一、路由的使用

  • 当一个路由链接被触发时会去路由配置中匹配;
  • 最终找到对应组件;
  • 在路由出口显示出来;

1.1 base 元素

大多数带路由的应用都要在index.html的 <head> 标签下先添加一个 <base> 元素,来告诉路由器该如何合成导航用的 URL。

1
2
3
4
5
6
7
8
9
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <base href="/">    <!-- Set the base href -->
     </head>
     <body>
       <app-root></app-root>
     </body>
    </html>

1.2 导入路由库

1
    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 路由出口

1
2
      <router-outlet></router-outlet>
      <!-- Routed views go here -->

1.5 路由器链接

a 标签上的 RouterLink 指令让路由器得以控制这个 a 元素。

1
2
3
4
5
6
    <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 重定向路由

1
2
3
4
5
      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 路由参数传递

路由配置:

1
      { path: 'hero/:id', component: HeroDetailComponent }

路由传参:

1
      <a routerLink="['/hero', hero.id]" >Heroes</a>

2.2.2 ActivatedRoute获取参数

从路由器(router)包中导入 Router、ActivatedRoute 和 Params 类。

1
2
     import { Router, ActivatedRoute, ParamMap } from '@angular/router';
     import { switchMap } from 'rxjs/operators';

通常,你会直接写一个构造函数,让 Angular 把组件所需的服务注入进来,自动定义同名的私有变量,并把它们存进去。

1
2
3
4
5
      constructor(
        private route: ActivatedRoute,
        private router: Router,
        private service: HeroService
      ) {}

然后,在 ngOnInit 方法中,你用 ActivatedRoute 服务来接收路由的参数
switchMap 操作符: 会取消以前未完成的在途请求,重新获取新的数据;

1
2
3
4
5
6
      ngOnInit() {
        this.hero$ = this.route.paramMap.pipe(
          switchMap((params: ParamMap) =>
            this.service.getHero(params.get('id')))
        );
      }

Snapshot(快照):组件的实例永远不会被复用,那就可以使用快照;

1
2
3
4
      ngOnInit() {
        let id = this.route.snapshot.paramMap.get('id');
        this.hero$ = this.service.getHero(id);
      }

2.3导航

路由的 navigate 方法同样接受一个单条目的链接参数数组,你也可以把它绑定到 [routerLink] 指令上。 它保存着到 HeroListComponent 组件的路径:

1
        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 属性

1
2
3
4
      {
        path: 'admin',
        loadChildren: 'app/admin/admin.module#AdminModule',
      },