Angular4 第三章(下)路由守卫

来源:互联网 发布:真王暗器进阶数据 编辑:程序博客网 时间:2024/06/05 18:05

路由守卫,实际意义是拦截器,在你进入路由或离开路由执行一些逻辑。

1.路由守卫有三种:

(1)CanActivate:处理导航到某路由的情况

(2)CanDeactivate:处理从当前路由离开的情况

(3)Resove 在路由激活之前获取路由数据

2.路由守卫实战:

CanActivate

第一步:写出CanActivate路由守卫的验证规则

创建文件 app/guard/permission.guard.ts

import {CanActivate} from '@angular/router';export class PermissionGuard implements CanActivate{  canActivate(){      var hasPermission: boolean = Math.random()  < 0.5;      if( !hasPermission )      {            console.log("用户无权访问股票详情");      }      return hasPermission;  }}
第二步:将路由守卫配置到路由配置,在app-routing.module.ts

import {StockResolve} from './guard/stock.resolve';const routes: Routes = [  {path: '', redirectTo: '/home', pathMatch: 'full'},  {path: 'home', component: HomeComponent  }, // 默认展示HomeComponnet  {path: 'consult', component: ConsultComponent, outlet: 'aux'},   // SellerListComponen只能能显示在aux的插座上  {    path: 'stock/:id', component: StockComponent, data: [{isPro: true}],     children: [        {path: '', component: BuyerListComponent},        {path: 'seller/:id', component: SellerListComponent}     ],      canActivate: [PermissionGuard],  },  {path: '**', component: Code404Component}];
第三步:需要在app.module.ts中提供器上声明   PermissionGuard
 providers: [PermissionGuard],
此时 CanActivate路由就此完成。

【CanDeactivate】

第一步:写出CanDeactivate路由守卫的验证规则

 (1)创建文件 app/guard/focus.guard.ts

import {CanDeactivate} from '@angular/router';import {StockComponent} from '../stock/stock.component';export class FocusGuard implements CanDeactivate<StockComponent> {    //StockComponent 表示保护的组件,可以拿到当前的组件    canDeactivate(component: StockComponent) {        if ( component.isFocus() ) {            return true;        }else {            return window.confirm( '不关注就离开吗?' );        }    }  }
(2)需要在StockComponent组件中声明一个isFocus()方法
export class StockComponent implements OnInit {  private focus = false;  constructor(private routeInfo: ActivatedRoute) {}  ngOnInit() {  }  isFocus() {    return this.focus;  }}

(3)StockComponent 的模板上

<input type="button" (click)="focus=true" value="关注" />

第二步:将路由守卫配置到路由配置,在app-routing.module.ts

const routes: Routes = [{path: '', redirectTo: '/home', pathMatch: 'full'},{path: 'home', component: HomeComponent  }, // 默认展示HomeComponnet{path: 'consult', component: ConsultComponent, outlet: 'aux'}, // SellerListComponen只能能显示在aux的插座上{  path: 'stock/:id', component: StockComponent, data: [{isPro: true}],   children: [      {path: '', component: BuyerListComponent},      {path: 'seller/:id', component: SellerListComponent}   ],    canActivate: [PermissionGuard],    canDeactivate: [FocusGuard]},{path: '**', component: Code404Component}];


第三步:需要在app.module.ts中提供器上声明  FocusGuard

 providers: [PermissionGuard,FocusGuard],

【Resove】

1.resove守卫要解决的问题:以Stock组件为例

(1)stock.component.ts

import { Component, OnInit } from '@angular/core';import { ActivatedRoute, Params } from '@angular/router';@Component({  selector: 'app-stock',  templateUrl: './stock.component.html',  styleUrls: ['./stock.component.css']})export class StockComponent implements OnInit {  public stock: Stock;  constructor() {}  ngOnInit() {    }}export class Stock {  constructor(public id: number, public name: string) {}}

(2)模板中

<p>股票stock.id是{{stock.id}}</p><p>股票stock.name是{{stock.name}}</p>

此时会报错因为stock为空2.解决问题:

Resove守卫在进入组件之前将stock赋值

第一步:写出Resove路由守卫的验证规则

 (1)创建文件 app/guard/stock.resove.ts

import { Router, Resolve,  ActivatedRouteSnapshot,  RouterStateSnapshot} from '@angular/router';import {Stock} from '../stock/stock.component';import { Injectable } from '@angular/core';import { Observable } from 'rxjs/Observable';@Injectable()  //使当前类支持依赖注入,@Componnent()继承了@Injectable()export class StockResolve implements Resolve<Stock> {  constructor( private router: Router){     //Router 类型的对象可以使用导航 this.router.navigate(['/home']);  }  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Stock| Observable<Stock> |Promise<Stock>{    // ActivatedRouteSnapshot类型的对象可以取到路由参数     var id = route.params['id'];     if ( id == 1) {         return new Stock(1,"IBM");     }else {       this.router.navigate(['/home']);       return undefined;     }  }}

第二步:将路由守卫配置到路由配置,在app-routing.module.ts

const routes: Routes = [  {path: '', redirectTo: '/home', pathMatch: 'full'},  {path: 'home', component: HomeComponent  }, // 默认展示HomeComponnet  {path: 'consult', component: ConsultComponent, outlet: 'aux'},   // SellerListComponen只能能显示在aux的插座上  {    path: 'stock/:id', component: StockComponent, data: [{isPro: true}],     children: [        {path: '', component: BuyerListComponent},        {path: 'seller/:id', component: SellerListComponent}     ],    //  canActivate: [PermissionGuard],    //  canDeactivate: [FocusGuard],    resolve:{      stock:StockResolve    }  },  {path: '**', component: Code404Component}];

第三步:需要在app.module.ts中提供器上声明  StockResove

 providers: [PermissionGuard,FocusGuard,StockResolve],
第四步:在stock.component.ts中执行给声明的stock对象赋值

import { Component, OnInit } from '@angular/core';import { ActivatedRoute, Params } from '@angular/router';@Component({  selector: 'app-stock',  templateUrl: './stock.component.html',  styleUrls: ['./stock.component.css']})export class StockComponent implements OnInit {  public stock: Stock;  constructor(private routeInfo: ActivatedRoute) {}  ngOnInit() {    this.routeInfo.data.subscribe((data:{stock:Stock})=>{       this.stock=data.stock;    })  }}export class Stock {  constructor(public id: number, public name: string) {}}
此时 :

(data:{stock:Stock})里面的stock是app-routing.module.ts中的
resolve:{stock:StockResolve}中的stock,Stock是类型









原创粉丝点击