基础
大多数带路由的应用都要在index.html
的<head>标签下先添加一个<base>元素,来告诉路由器该如何合成导航用的 URL 。
如果app文件夹是该应用的根目录,那就把href的值设置为下面这样:
<base href="/">
另外如果app不是根路径则需要在<head>中使用
<script>document.write('<base href="' + document.location + '" />');</script>
路由配置
首选方案是用带有“路由数组”的 provideRouter 工厂函数( [provideRouter(routes)] )来启动此应用。
myApp.routes.ts
import {RouterConfig,provideRouter} from"@angular/router";
import {LoginComponent} from"./login/login.component";
import {HomeComponent} from"./shared/default/home.component";
/**
*Created by Administrator on 2016-07-22.
*/
const routes:RouterConfig =[
{path:'',component:HomeComponent},
{path:'login',component:LoginComponent}
]
export const myAppRouterProviders=[
provideRouter(routes)
RouterConfig 是一个 路由 数组,它会决定如何导航。 每个 Route 会把一个 URL 的 path 映射到一个组件。
path 中 不能用斜线 / 开头。路由器会为我们解析和生成 URL ,以便在多个视图间导航时,可以自由使用相对路径和绝对路径。
第三个路由中的 :id 是一个路由参数的令牌 (Token) 。比如 /hero/42 这个 URL 中,“ 42 ”就是 id 参数的值。此 URL 对应的 HeroDetailComponent 组件将据此查找和展现 id 为 42 的英雄。
我们将把这份配置数组传给 provideRouter() 函数,它返回一个经过配置的 Router 服务提供商(以及别的东西)。
最后,我们通过 appRouterProviders 数组导出这个提供商,以便我们以后将来在 main.ts 中简单的注册路由器依赖。目前我们还没有注册任何别的提供商,但很快就会这么做了!
路由使用
有了这份配置,当本应用在浏览器中的 URL 变为 /heroes 时,路由器就会匹配到 path 为 heroes 的 Route ,并在宿主视图中的 RouterOutlet 中显示 HeroListComponent 组件。
现在,我们已经有了配置好的一些路由,还找到了渲染它们的地方,但又该如何导航到它呢?固然,从浏览器的地址栏直接输入 URL 也能做到,但是大多数情况下,导航是某些用户操作的结果,比如点击一个 A 标签。
我们把一个 RouterLink 指令添加到这个 A 标签上,并把该指令绑定到一个能返回路由链接数组(链接参数数组 )的模板表达式上。 路由器最终会把此数组解析成一个 URL 和一个组件视图。
一个模板中只能有一个未命名的 <router-outlet> 。 但路由器可以支持多个 命名的 插座( outlet )。
RouterLink 绑定
在插座上方的 A 标签中,有一个绑定 RouterLink 指令的属性绑定 ,就像这样:[routerLink]="[...]" 。我们从路由库中导入了 RouterLink 。
等号( = )右侧的模板表达式返回一个链接参数数组 。
链接参数数组中存放导航时所需的那些要素:
指向目标组件的路由中的 path 属性
可选的路由参数和查询参数,它们会被编入到该路由的 URL 中
这个例子中的数组都只有一个字符串参数,也就是我们以前配置过的路由中的 path 部分。目前还没有用到路由参数。
注意:RouterLink和RouterOutlet是ROUTER_DIRECTIVES集合中的指令。记住把它们加入@Component元数据的directives数组中。
import{ROUTER_DIRECTIVES} from "@angular/router";
…..
directives:[ROUTER_DIRECTIVES]
把应用组织为一些特性区
典型的应用中有多个特性区 ,每个区都是一个“功能岛”,它们有自己的工作流、实现一个特定的业务目标。
我们可以继续把文件全添加到 app/ 目录中。但那么做不太现实,并且最终将无法维护。因此,把每个特性区都放进自己的目录中会更好一些。
第一步: 创建一个独立的 app/heroes/ 文件夹,并在其中添加属于英雄管理 特性区的文件。
第二步: 为每个特性区创建它自己的路由配置文件。
import {RouterConfig} from"@angular/router";
import { ChangePasswordComponent} from"../../system/changepassword/changepassword.component";
import {AdminMenuComponent} from"../adminmenu/adminmenu";
export const topNavRoutes:RouterConfig=[
{path:"userNav",component:AdminMenuComponent},102); line-height:26px"> {path:'changepassword/:id',component:ChangePasswordComponent}
];
记住此处需要export这个路由表
第三步:把特性区的路由合并到应用程序的路由中。
import {topNavRoutes} from"./shared/topnav/topnav.routes";
import {loginRoutes} from"./login/login.routes";
export const routes:RouterConfig =[
{path:'home',102); line-height:26px"> ...loginRoutes,102); line-height:26px"> ...topNavRoutes
这里的provideRouter即是将配置的路由表注入到应用中,这样在整个应用中都可以使用这个路由表。
这里注意通过“…”会将特性区配置的路由表扁平化到app路由配置中
另外,通常情况我们需要对根路径做一个重定向处理。由“/”定向到“/home”中
这样做的结果是, app.routes.ts 文件不用再了解特性区的具体知识,比如组件细节和路由细节等等。这样,当我们要为特性区加入更多的组件和路由,该文件将不用做任何变化。这真是为每个特性区单独创建路由配置的关键性优点,这集中体现了模块化开发的思路。
命令式地导航
首先需要在组件的构造函数中注入Router,然后使用router进行路由导航
import {Router} from"@angular/router";
…..
constructor(private router:Router){
}
无参数导航
this.router.navigate(['/'])
带参数导航
this.router.navigate(['/menu,menu.id]);