Angular2 之 路由与导航
导航是很简单的,只是不同页面之间的切换,路由是实现导航的一种。 一个url对应的一个页面,在angular2中是一个组件。定义一个规则。 设计的时候,先去 基础知识
const appRoutes: Routes = [
{
path:'',// empty path匹配各级路由的默认路径。 它还支持在不扩展URL路径的前提下添加路由。
component: DashboardComponent
},{
path: 'dashboard',component: DashboardComponent
},{
path: 'loopback',component: LoopbackComponent
},{
path: 'heroparent',component: HeroParentComponent
},{
path:'version',component: VersionParentComponent
},{
path: '**',// **代表该路由是一个通配符路径。如果当前URL无法匹配上我们配置过的任何一个路由中的路径,路由器就会匹配上这一个。当需要显示404页面或者重定向到其它路由时,该特性非常有用。
component: DashboardComponent,}
];
export const appRoutingModule: ModuleWithProviders = RouterModule.forRoot(appRoutes);
路由模块最开始的路由,我们是直接写在 import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule,Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { CrisisListComponent } from './crisis-list.component';
import { HeroListComponent } from './hero-list.component';
const appRoutes: Routes = [
{ path: 'crisis-center',component: CrisisListComponent },{ path: 'heroes',component: HeroListComponent }
];
@NgModule({
imports: [
BrowserModule,FormsModule,RouterModule.forRoot(appRoutes)
],declarations: [
AppComponent,HeroListComponent,CrisisListComponent
],bootstrap: [ AppComponent ]
})
export class AppModule {
}
但是这样不方便,所以我们要进行路由的分离,重构成我们自己的路由模块。like this: const appRoutes: Routes = [
{
path:'',component: DashboardComponent,}
];
export const appRoutingModule: ModuleWithProviders = RouterModule.forRoot(appRoutes);
同样我们还可以写多个路由模块。但是我们必须在 组件路由我们需要将一些特征区域分割开来,做成自己单独的模块。必如hero模块。在这里,我们需要hero单独的导航,这也就是组件路由。 @NgModule({
imports: [
RouterModule.forChild([
{ path: 'heroes',component: HeroListComponent },{ path: 'hero/:id',component: HeroDetailComponent },{ path:'heroform',component: HeroFormComponent },])
],exports: [
RouterModule
]
})
export class HeroRoutingModule { }
我们还有另外一中类型的路由组织方式,路由树的形式。 const crisisCenterRoutes: Routes = [
{
path: '',redirectTo: '/crisis-center',pathMatch: 'full'
},{
path: 'crisis-center',component: CrisisCenterComponent,children: [
{
path: '',component: CrisisListComponent,children: [
{
path: ':id',component: CrisisDetailComponent,},{
path: '',component: CrisisCenterHomeComponent
}
]
}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(crisisCenterRoutes)
],exports: [
RouterModule
]
})
export class CrisisCenterRoutingModule { }
{ path: '',redirectTo: '/crisis-center',pathMatch: 'full' },
路由守卫简介路由守卫,应用在这个路由不是对所有导航都有效的,是有一些前置条件的,只有当这些前置条件满足的时候,才能被导航到该页面。 可以在路由配置中添加守卫来进行处理。守卫可以返回一个 路由器支持多种守卫
使用规则在分层路由的每个级别上,我们都可以设置多个守卫。 路由器会先按照从最深的子路由由下往上检查的顺序来检查CanDeactivate守护条件。 然后它会按照从上到下的顺序检查CanActivate守卫。 如果任何守卫返回false,其它尚未完成的守卫会被取消,这样整个导航就被取消了。 CanActivate使用 具体的守卫规则要看AuthGuard类的实现。而AuthGuard 类是需要继承CanActivate 类的: import { AuthGuard } from '../auth-guard.service';
const adminRoutes: Routes = [
{
path: 'admin',component: AdminComponent,canActivate: [AuthGuard],// 重点
children: [
{
path: '',children: [
{ path: 'crises',component: ManageCrisesComponent },component: ManageHeroesComponent },{ path: '',component: AdminDashboardComponent }
],}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(adminRoutes)
],exports: [
RouterModule
]
})
export class AdminRoutingModule {}
CanActivateChild 守卫自路由就像我们可以通过CanActivate来守卫路由一样,我们也能通过CanActivateChild守卫来保护子路由。CanActivateChild守卫的工作方式和CanActivate守卫很相似,不同之处在于它会在每个子路由被激活之前运行。我们保护了管理特性模块不受未授权访问,也同样可以在特性模块中保护子路由。 这个使用起来比较简单,只需要在需要守卫的子路由的配置上添加即可。而AuthGuard 类是需要继承canActivateChild 类的: const adminRoutes: Routes = [
{
path: 'admin',component: AdminComponent,canActivate: [AuthGuard],children: [
{ // 无组件路由,相当于分组
path: '',canActivateChild: [AuthGuard],// 守卫子路由
children: [
{ path: 'crises',component: ManageCrisesComponent },{ path: 'heroes',component: ManageHeroesComponent },{ path: '',component: AdminDashboardComponent }
]
}
]
}
];
CanDeactivate 处理未保存的更改在现实世界中,我们得先把用户的改动积累起来。 我们可能不得不进行跨字段的校验,可能要找服务器进行校验,可能得把这些改动保存成一种待定状态,直到用户或者把这些改动作为一组进行确认或撤销所有改动。 当用户要导航到外面时,该怎么处理这些既没有审核通过又没有保存过的改动呢? 我们不能马上离开,不在乎丢失这些改动的风险,那显然是一种糟糕的用户体验。 我们应该暂停,并让用户决定该怎么做。如果用户选择了取消,我们就留下来,并允许更多改动。如果用户选择了确认,那就进行保存。 在等待服务器的答复时,我们没法阻塞它 —— 这在浏览器中是不可能的。 我们只能用异步的方式在等待服务器答复之前先停止导航。 Resolve主要实现的就是导航前预先加载路由信息。可以做到,当真正需要导航进来这个详情页面时,是不需要再去获取数据的。是提前加载好的。 CanLoad - 保护特性模块的加载前提异步路由,只要是懒惰加载特征区域。这样做的好处:
路由器用 const appRoutes: Routes = [
{
path: 'admin',loadChildren: 'app/admin/admin.module#AdminModule',}
];
export class AdminModule {}
简介我们已经使 我们可以用CanLoad守卫来保证只在用户已经登录并尝试访问管理特性区时才加载一次AdminModule。 几个概念无组件路由无组件路由,不借助组件对路由进行分组。来看AdminComponent const adminRoutes: Routes = [
{
path: 'admin',children: [
{ // 无组件路由
path: '',component: AdminDashboardComponent }
]
}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(adminRoutes)
],exports: [
RouterModule
]
})
export class AdminRoutingModule {}
预加载: 在后台加载特征区域每次导航成功发生时,路由器将查看惰性加载的特征区域的配置,并根据提供的策略作出反应。 预加载所有惰性加载的特征区域。 路由器还支持自定义预加载策略,用来精细控制预加载。 自定义预加载策略
链接参数数组链接参数数组保存路由导航时所需的成分:
e.g.我们可以把RouterLink指令绑定到一个数组,就像这样: <a [routerLink]="['/heroes']">Heroes</a>
e.g.在指定路由参数时,我们写过一个双元素的数组,就像这样: this.router.navigate(['/hero',hero.id]);
e.g.我们可以在对象中提供可选的路由参数,就像这样: <a [routerLink]="['/crisis-center',{ foo: 'foo' }]">Crisis Center</a>
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |