路由守卫
使用场景
分三种方式
案例:
1、CanActivate 路由守卫用法
在app内新增文件夹guard
新建login.guard.ts 模拟登陆状态;
调用CanActivate接口,return 的值为true视为登陆成功,可以下一步路由
import {CanActivate} from "@angular/router";
/*实现 CanActivate的接口*/
export class LoginGuard implements CanActivate{
canActivate(){
let loggedIn:boolean = Math.random() < 0.5;
if(!loggedIn){
console.log('用户未登陆');
}
return loggedIn;
}
}
路由配置app-routing.module.ts如下 :
....
{path:'product/:id',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:SellerInfoComponent},
],canActivate:[LoginGuard] },
....
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
/*依赖注入*/
providers:[LoginGuard],
})
....
2、canDeactivate路由守卫用法
在当前路由离开前, 做相关守卫,如提供客户还没保存,return值为true才通过。
示例:新建unsaved.guard.ts文件
import {CanDeactivate} from "@angular/router";
import {ProductComponent} from "../product/product.component";
/* <ProductComponent> 是泛型写法 */
export class UnsavedGuard implements CanDeactivate<ProductComponent>{
canDeactivate(component: ProductComponent){
return window.confirm("还没有保存");
}
}
路由配置app-routing.module.ts如下 :
...
{path:'product/:id',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:SellerInfoComponent},
],canActivate:[LoginGuard],
canDeactivate:[UnsavedGuard]
},
...
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
/*依赖注入*/
providers:[LoginGuard,UnsavedGuard],
})
3、Resolve 守卫,在路由激活前获取数据给模块渲染
3.1在guard中新建product.resolve.ts定义逻辑
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from "@angular/router";
import {Product} from "../product/product.component";
import {Injectable} from "@angular/core";
@Injectable()
export class ProductResolve implements Resolve<Product>{
constructor(private router:Router){
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
let productId:number = route.params['id'];
if(productId == 1){
return new Product(1,'iPhone7');
}else{
this.router.navigate(['/home']);
return undefined;
}
}
}
3.2 在product组件中定义Product对象
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Params} from "@angular/router";
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
private productId:number;//定义接收的ID变量
private productName:string;//定义接收的productName变量
constructor(private routeInfo:ActivatedRoute) { }
ngOnInit() {
/* 通过参数订阅取得数据 */
this.routeInfo.params.subscribe((param:Params)=>this.productId = param['id']);
this.routeInfo.data.subscribe((data:{product:Product})=>{
this.productId = data.product.id;
this.productName = data.product.name;
})
/*通过 queryParams 方法取得参数快照*/
// this.productId = this.routeInfo.snapshot.params['id'];
}
}
3.3在product组件模板中定义输出变量
<div class="product">
<p>
这是一个商品组件
</p>
<p>
查询参数传递过来的组件ID:{{productId}}
</p>
<p>
商品名称是:{{productName}}
</p>
<br>
<hr>
<a [routerLink]="['./']">商品的描述</a>
<a [routerLink]="['./seller',99]">销售员信息</a>
<router-outlet></router-outlet>
</div>
3.4 在app-routing.module.ts中定义调用
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {HomeComponent} from "./home/home.component";
import {ProductComponent} from "./product/product.component";
import {Code404Component} from "./code404/code404.component";
import {ProductDescComponent} from "./product-desc/product-desc.component";
import {SellerInfoComponent} from "./seller-info/seller-info.component";
import {ChatComponent} from "./chat/chat.component";
import {LoginGuard} from "./guard/login.guard";
import {UnsavedGuard} from "./guard/unsaved.guard";
import {ProductResolve} from "./guard/product.resolve";
const routes: Routes = [
{path:'',redirectTo:'/home',pathMatch:'full'},
{path:'chat',component:ChatComponent,outlet:'aux'},
{path:'home',component:HomeComponent},
{path:'product/:id',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:SellerInfoComponent},
],resolve:{
product:ProductResolve
}
},
/* 路由配 通配符路由通常放最后面 */
{path:'**',component:Code404Component},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
/*依赖注入*/
providers:[LoginGuard,UnsavedGuard,ProductResolve],
})
export class AppRoutingModule { }
路由部分源码:
链接: https://pan.baidu.com/s/1bBZYJs 密码: ukwe