Angular 2(三): 子路由和守卫

子路由

子路由相对于根路由的概念而来,示例:children:数组,配置路由相关信息

路由配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
path:'product',
component:ProductComponent,
children:[ //关键字
{
path:'',
component:ProductDescComponent //商品简介组件
},
{
path:'seller/:id',
component:SellerDetailComponent //具体商品信息组件
}
]
}

父组件:

1
2
3
4
注意[routerLink] = "['./']",路径中加"."指明是匹配子路由
<a [routerLink] = "['./']">商品简介</a>
<a [routerLink] = "['./seller/3']">商品信息</a>
<router-outlet></router-outlet> //供子组件使用的路由插座


辅助路由

概览:辅助路由可以有多个,根据“name”字段来匹配

  • 路由配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    path:'xxx',
    component:XComponent,
    outlet:"aux", //匹配路由名字,确定放在哪个辅助路由上
    },
    {
    path:'yyy',
    component:YComponent,
    outlet:"aux",
    }
  • 父组件写法,假设是在app.component.html中
    1
    2
    3
    4
    5
    6
    <a [routerLink]="['/home',{ outlets:{ aux:"xxx" } }]">GOTO XXX</a>
    <a [routerLink]="['/home',{ outlets:{ aux:"yyy" } }]">GOTO YYY</a>
    <router-outlet></router-outlet> //主路由
    <router-outlet name="aux"></router-outlet> //辅助路由
    <router-outlet name="other"></router-outlet> //可以有多个辅助路由

路由守卫

路由守卫的意义在于,路由事件发生后,是否允许默认操作(比如,跳转到指定的页面)

如何使用?示例:

  • 路由文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import LoginGuard from "...";
    import TokenGuard from "...";
    const routes : Routes = [
    {
    path:'product',
    component:ProductComponent,
    //路由钩子对象(对应loginGuard.ts中的钩子接口)
    canActivate:[ //是否可以进入该组件
    LoginGuard //控制函数(路由钩子函数),只有当所有的函数都返回true时,才可以进入组件
    TokenGuard
    ]
    }
    ];
    @NgModule({
    import:[RouterModule.forRoot(routes)],
    exports:[RouterModule],
    providers:[ LoginGuard,TokenGuard ]
    })
  • 守卫文件:loginGuard.ts

    1
    2
    3
    4
    5
    6
    7
    export class LoginGuard implements CanActivate{
    CanActivate():boolean{ //接收一个boolean类型的返回值
    //处理逻辑,比如判断token是否有效
    //return true;
    return false;
    }
    }

增加一个CanDeactivate守卫,表示是否可以离开该组件(常用来检查用户填写的信息是否已经保存):

实现守卫(实现CanDeactivate守卫接口)接口,unSaveGuard.ts文件中
注意事项:

  • 该守卫需要接受一个组件作为参数(即保护的组件);
  • 在守卫函数中,需要创建组件的对象(comp),通过该对象获得组件内部的属性判断是否已经保存
1
2
3
4
5
6
7
8
9
10
11
12
import { CanDeactivate } from '...';
export class UnSaveGuard implements CanDeactivate<ProductComponent>{
canDeactivate(comp:ProductComponent){
//逻辑操作,对组件内部的变量进行验证是否已经保存
comp.varibleName;
//return true; //是否允许离开
return false;
}
}
  • 将守卫加入到路由配置中

    1
    2
    3
    4
    5
    6
    {
    path: 'product',
    component: ProductComponent,
    canActivate:[ LoginGuard,TokenGuard ],
    canDeactivate:[ UnSaveGuard ] //只有一系列函数都return true才可以顺利执行路由操作
    }
  • 在NgModule中配置

    1
    providers: [ loginGuard,TokenGuard,UnSaveGuard ]

resolve守卫

该守卫常用在进入下一个组件之前,执行服务获取下一个组件需要用到的数据,并带入组件中。
所以该组件需要可以被注入,在写时需要加入@Injectable()标识

  • 路由配置项改写

    1
    2
    3
    4
    5
    6
    7
    {
    path:'product',
    component:ProductComponent,
    resolve:{
    prod: ProductResolve //prod是传入组件中的参数集合的对象
    }
    }
  • 写productResolve.ts文件,提供ProductResolve函数

  • 该class需要指定返回的参数的格式,即:

    1
    2
    3
    4
    5
    6
    7
    export class ProductResolve implements Resolve<Product>{
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product>|Promise<Product>|Product {
    //发起请求,获取数据
    return data; //将解析好的数据传递到组件内部,之后订阅该字段获取数据
    }
    }
  • 在组建中取值(采用订阅的方式)

    1
    2
    3
    4
    5
    6
    7
    constructor(private routeInfo:ActivatedRoute){}
    ngOnInit(){
    this.routeInfo.data.subscribe((data:{prod:Product}) => {
    this.id = data.prod.id;
    })
    }

本章内容主要通过代码展示,比较粗略。如果发现文档中的错漏,或者涉及到具体问题,可以联系QQ:3265564490,备注:Angular 笔记