[Angular学习笔记]路由与导航

路由与导航

在用户使用应用程序时,Angular 的路由器能让用户从一个视图导航到另一个视图。

导入路由

Angular 的路由器是一个可选的服务,它用来呈现指定的 URL 所对应的视图。 它并不是 Angular 核心库的一部分,而是在它自己的 @angular/router 包中。 像其它 Angular 包一样,你可以从它导入所需的一切。

import { RouterModule, Routes } from '@angular/router';

配置路由

每个带路由的 Angular 应用都有一个Router(路由器)服务的单例对象。 当浏览器的 URL 变化时,路由器会查找对应的 Route(路由),并据此决定该显示哪个组件。

路由器需要先配置才会有路由信息。 下面的例子创建了五个路由定义,并用 RouterModule.forRoot() 方法来配置路由器, 并把它的返回值添加到 AppModule 的 imports 数组中。

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 } // 打印所有路由事件
  )
  ],
...
})
export class AppModule { }

这里的路由数组 appRoutes 描述如何进行导航。 把它传给 RouterModule.forRoot() 方法并传给本模块的 imports 数组就可以配置路由器。

每个 Route 都会把一个 URL 的 path 映射到一个组件。 注意,path 不能以**斜杠(/)**开头。 路由器会为解析和构建最终的 URL,这样当你在应用的多个视图之间导航时,可以任意使用相对路径和绝对路径。

第二个路由中的 :id 是一个路由参数的令牌(Token)。比如 /hero/42 这个 URL 中,“42”就是 id 参数的值。 此 URL 对应的 HeroDetailComponent 组件将据此查找和展现 id 为 42 的英雄。 在本章中稍后的部分,你将会学习关于路由参数的更多知识。

第三个路由中的 data 属性用来存放于每个具体路由有关的任意信息。该数据可以被任何一个激活路由访问,并能用来保存诸如 页标题、面包屑以及其它静态只读数据。本章稍后的部分,你将使用resolve 守卫来获取动态数据。

第四个路由中的空路径('')表示应用的默认路径,当 URL 为空时就会访问那里,因此它通常会作为起点。 这个默认路由会重定向到 URL /heroes,并显示 HeroesListComponent

最后一个路由中的 ** 路径是一个通配符。当所请求的 URL 不匹配前面定义的路由表中的任何路径时,路由器就会选择此路由。 这个特性可用于显示“404 - Not Found”页,或自动重定向到其它路由。

这些路由的定义顺序是刻意如此设计的。路由器使用先匹配者优先的策略来匹配路由,所以,具体路由应该放在通用路由的前面。在上面的配置中,带静态路径的路由被放在了前面,后面是空路径路由,因此它会作为默认路由。而通配符路由被放在最后面,这是因为它能匹配上每一个 URL,因此应该只有在前面找不到其它能匹配的路由时才匹配它。

如果你想要看到在导航的生命周期中发生过哪些事件,可以使用路由器默认配置中的 enableTracing 选项。它会把每个导航生命周期中的事件输出到浏览器的控制台。 这应该只用于调试。你只需要把 enableTracing: true 选项作为第二个参数传给 RouterModule.forRoot() 方法就可以了。

路由出口

RouterOutlet 是一个来自路由模块中的指令,它的用法类似于组件。 它扮演一个占位符的角色,用于在模板中标出一个位置,路由器将会把要显示在这个出口处的组件显示在这里。

<router-outlet></router-outlet>

路由器链接

现在,你已经有了配置好的一些路由,还找到了渲染它们的地方,但又该如何导航到它呢?固然,从浏览器的地址栏直接输入 URL 也能做到,但是大多数情况下,导航是某些用户操作的结果,比如点击一个 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>

a 标签上的 RouterLink 指令让路由器得以控制这个 a 元素。 这里的导航路径是固定的,因此可以把一个字符串赋给 routerLink(“一次性”绑定)。

如果需要更加动态的导航路径,那就把它绑定到一个返回链接参数数组的模板表达式。 路由器会把这个数组解析成完整的 URL。

路由链接的激活状态

RouterLinkActive 指令会基于当前的 RouterState为活动的 RouterLink 切换所绑定的 css 类。

在每个 A 标签上,你会看到一个到 RouterLinkActive 的属性绑定,形如 routerLinkActive="…"。

等号右边的模板表达式包含一些用空格分隔的 CSS 类名,当这个链接激活时,路由器将会把它们加上去(并在处于非活动状态时移除)。你还可以把 RouterLinkActive 设置为一个类组成的字符串,如 [routerLinkActive]="‘active fluffy’",或把它绑定到一个返回类似字符串的组件属性。

路由链接的激活状态会向下级联到路由树中的每个层级,所以,父子路由链接可能会同时激活。要覆盖这种行为,可以把 [routerLinkActiveOptions] 绑定为 { exact: true } 表达式,这样  RouterLink只有当 URL 与当前 URL 精确匹配时才会激活。

路由器状态

在导航时的每个生命周期成功完成时,路由器会构建出一个 ActivatedRoute组成的树,它表示路由器的当前状态。 你可以在应用中的任何地方用 Router 服务及其 routerState属性来访问当前的 RouterState 值。
RouterState 中的每个 ActivatedRoute 都提供了从任意激活路由开始向上或向下遍历路由树的一种方式,以获得关于父、子、兄弟路由的信息。

路由信息获取

该路由的路径和参数可以通过注入进来的一个名叫ActivatedRoute的路由服务来获取。 它有一大堆有用的信息,包括:

属性说明
url路由路径的 Observable 对象,是一个由路由路径中的各个部分组成的字符串数组。
data一个 Observable,其中包含提供给路由的 data 对象。也包含由解析守卫(resolve guard)解析而来的值。
paramMap一个 Observable,其中包含一个由当前路由的必要参数和可选参数组成的map对象。用这个 map 可以获取来自同名参数的单一值或多重值。
queryParamMap一个 Observable,其中包含一个对所有路由都有效的查询参数组成的map对象。 用这个 map 可以获取来自查询参数的单一值或多重值。
fragment一个适用于所有路由的 URL 的 fragment(片段)的 Observable
outlet要把该路由渲染到的 RouterOutlet 的名字。对于无名路由,它的路由名是 primary,而不是空串。
routeConfig用于该路由的路由配置信息,其中包含原始路径。
parent当该路由是一个子路由时,表示该路由的父级 ActivatedRoute
firstChild包含该路由的子路由列表中的第一个 ActivatedRoute
children包含当前路由下所有已激活的子路由

有两个旧式属性仍然是有效的,但它们不如其替代品那样强力,建议不再用它们,它们还将在未来的 Angular 版本中废弃
params —— 一个 Observable 对象,其中包含当前路由的必要参数和可选参数。请改用 paramMap
queryParams —— 一个 Observable 对象,其中包含对所有路由都有效的查询参数。请改用 queryParamMap

路由事件

在每次导航中,Router 都会通过 Router.events 属性发布一些导航事件。这些事件的范围涵盖了从开始导航到结束导航之间的很多时间点。下表中列出了全部导航事件:

路由器事件说明
NavigationStart本事件会在导航开始时触发。
RouteConfigLoadStart本事件会在 Router惰性加载 某个路由配置之前触发。
RouteConfigLoadEnd本事件会在惰性加载了某个路由后触发。
RoutesRecognized本事件会在路由器解析完 URL,并识别出了相应的路由时触发
GuardsCheckStart本事件会在路由器开始 Guard 阶段之前触发。
ChildActivationStart本事件会在路由器开始激活路由的子路由时触发。
ActivationStart本事件会在路由器开始激活某个路由时触发。
GuardsCheckEnd本事件会在路由器成功完成了 Guard 阶段时触发。
ResolveStart本事件会在 Router 开始解析(Resolve)阶段时触发。
ResolveEnd本事件会在路由器成功完成了路由的解析(Resolve)阶段时触发。
ChildActivationEnd本事件会在路由器激活了路由的子路由时触发。
ActivationEnd本事件会在路由器激活了某个路由时触发。
NavigationEnd本事件会在导航成功结束之后触发。
NavigationCancel本事件会在导航被取消之后触发。 这可能是因为在导航期间某个路由守卫返回了 false
NavigationError这个事件会在导航由于意料之外的错误而失败时触发。
Scroll本事件代表一个滚动事件。

总结一下

该应用有一个配置过的路由器。 外壳组件中有一个 RouterOutlet,它能显示路由器所生成的视图。 它还有一些 RouterLink,用户可以点击它们,来通过路由器进行导航。

下面是一些路由器中的关键词汇及其含义:

路由器部件含义
Router(路由器)为激活的 URL 显示应用组件。管理从一个组件到另一个组件的导航
RouterModule一个独立的 NgModule,用于提供所需的服务提供商,以及用来在应用视图之间进行导航的指令。
Routes(路由数组)定义了一个路由数组,每一个都会把一个 URL 路径映射到一个组件。
Route(路由)定义路由器该如何根据 URL 模式(pattern)来导航到组件。大多数路由都由路径和组件类构成。
RouterOutlet(路由出口)该指令(<router-outlet>)用来标记出路由器该在哪里显示视图。
RouterLink(路由链接)这个指令把可点击的 HTML 元素绑定到某个路由。点击带有 routerLink 指令(绑定到字符串链接参数数组)的元素时就会触发一次导航。
RouterLinkActive(活动路由链接)当 HTML 元素上或元素内的routerLink变为激活或非激活状态时,该指令为这个 HTML 元素添加或移除 CSS 类。
ActivatedRoute(激活的路由)为每个路由组件提供提供的一个服务,它包含特定于路由的信息,比如路由参数、静态数据、解析数据、全局查询参数和全局碎片(fragment)。
RouterState(路由器状态)路由器的当前状态包含了一棵由程序中激活的路由构成的树。它包含一些用于遍历路由树的快捷方法。
链接参数数组这个数组会被路由器解释成一个路由操作指南。你可以把一个RouterLink绑定到该数组,或者把它作为参数传给Router.navigate方法。
路由组件一个带有RouterOutlet的 Angular 组件,它根据路由器的导航来显示相应的视图。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值