应用场景
只有当用户已经登陆并拥有某些权限时才能进入某些路由
一个有多个表单组件组成的向导,例如注册流程,用户只有在当前路由的组件中填写了满足要求的信息才可以导航到下一个路由
当用户未执行保存操作而试图离开当前导航时提醒用户
路由守卫分类
CanActivate:处理导航到某路由的情况。当不满足CanActivate的条件时,就不导航。
CanDeactivate:处理从当前路由离开的情况。当不满足CanDeactivate的条件,就不能离开当前路由。
Resolve:在路由激活之前获取路由数据。这样在展示路由的时候就可以立刻把数据展示给用户。
CanActivate DEMO
1.创建守卫ts guard/login.guard.ts
import { CanActivate } from "@angular/router";
export class LoginGuard implements CanActivate {
//满足条件才可以进入路由
canActivate() {
let loggedIn: boolean = Math.random() < 0.5;
if (!loggedIn) {
console.log("用户未登录");
}
return loggedIn;
}
}
2.在路由上添加CanActivate 路由守卫
import { LoginGuard } from './guard/login.guard';
const routes: Routes = [
{ path: '**', component: Code404Component ,canActivate: [LoginGuard]}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [LoginGuard]
})
CanDeactivate DEMO
1.创建守卫ts guard/unsaved.guard.ts
import { CanDeactivate } from '@angular/router';
import { ProductComponent } from "../product/product.component";
export class UnsavedGuard implements CanDeactivate<ProductComponent>{
//要是不满足CanDeactivate的条件 就不能离开当前路由
canDeactivate(_component: ProductComponent) {
return window.confirm("您还没有保存,确认离开吗?");
}
}
2.在路由上添加CanDeactivate路由守卫
import { UnsavedGuard } from './guard/unsaved.guard';
const routes: Routes = [
{ path: '**', component: Code404Component ,canDeactivate:[UnsavedGuard]}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [LoginGuard, UnsavedGuard]
})
Resolve DEMO
1.在productComponent中编写Product类的构造函数,并订阅两个属性
private productId: number;
private productName: string;
ngOnInit() {
//参数订阅
this.routeInfo.data.subscribe((data: { product: Product }) => {
this.productId = data.product.id;
this.productName = data.product.name;
})
}
}
export class Product {
constructor(public id: number, public name: string) {
}
}
2.创建守卫ts guard/product.guard.ts
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router";
import { Product } from "../product/product.component";
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
//在进入到商品信息页之前,预先从服务器读取数据,读好了之后带着信息进到路由里面
//首先要先声明一个泛型,这个泛型就是resolve要解析出来的类型
//需要用Injectable装饰器,只有这样router才能注入进来
@Injectable()
export class ProductResolve implements Resolve<Product>{
constructor(private router: Router) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product> | Promise<Product> | Stock {
let productId:number = route.params['id'];
//路由路径id为1时
if (productId == 1) {
console.log('这里是1');
return new Product(1, 'iPhone7'); // 返回实例化值 Product
} else {
this.router.navigate(['/home']);//产品不是1,导航到home组件上
return undefined;
}
}
}
3.在路由上添加Resolve 路由守卫
import { ProductResolve } from './guard/product.resolve';
const routes: Routes = [
{ path: '**', component: Code404Component , resolve: {
product:ProductResolve
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [ProductResolve]
})