美文网首页
Angular guard 路由守卫的简介

Angular guard 路由守卫的简介

作者: mm_tang | 来源:发表于2020-03-17 15:09 被阅读0次

啥时候会用到路由守卫?

  1. 该用户可能无权导航到目标组件。
  2. 可能用户得先登录(认证)。
  3. 在显示目标组件前,你可能得先获取某些数据。
  4. 在离开组件前,你可能要先保存修改。
  5. 你可能要询问用户:你是否要放弃本次更改,而不用保存它们?

路由守卫相关的接口

  1. 用CanActivate来处理导航到某路由的情况。 =》 进入路由的时候触发
  2. 用CanActivateChild来处理导航到某子路由的情况。 =》 进入路由的时候触发
  3. 用CanDeactivate来处理从当前路由离开的情况。 =》 离开路由的时候触发
  4. 用Resolve在路由激活之前获取路由数据。
  5. 用CanLoad来处理异步导航到某特性模块的情况。

接下来通过具体的实例介绍如何使用CanActivate,CanActivateChild,CanDeactivate😺

CanActivate与CanActivateChild

守卫可以用同步的方式返回一个布尔值。但在很多情况下,守卫无法用同步的方式给出答案。 守卫可能会向用户问一个问题、把更改保存到服务器,或者获取新数据,而这些都是异步操作。
因此,路由的守卫可以返回一个 Observable<boolean> 或 Promise<boolean>,并且路由器会等待这个可观察对象被解析为 true 或 false。 所以接下来的代码我们会用两个版本分别试验同步和异步的写法。

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { UserService } from '../../../../common/services/user.service';

@Injectable()
export class ExampleGuardService implements CanActivate, CanActivateChild {

 // version1.0 异步版

  public isBecomeUser$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
  constructor(private router: Router, private userService: UserService) {
    this.verifyAccess();
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.isBecomeUser$.filter(status => typeof status === 'boolean');
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.isBecomeUser$.filter(status => typeof status === 'boolean');
  }

  private verifyAccess() {
     // 这里是用来返回isBecomeUser$的值
     // 如果它返回 true,导航过程会继续
     // 如果它返回 false,导航过程就会终止,且用户留在原地。
     // 守卫还可以告诉路由器导航到别处,这样也会取消当前的导航。要想在守卫中这么做,就要返回 false;
  }
  
 // version2.0 同步版
 
  public canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const data = next.data;
    const {authName} = data;
    if (authName) {
      return this.checkAuth(authName);
    }
    return true;
  }

  public canActivateChild(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
   // CanActivateChild 守卫和 CanActivate 守卫很像。 它们的区别在于,CanActivateChild 会在任何子路由被激活之前运。
   // 所以他们的判断逻辑是相同的只是使用的地方不同。
   // 如果要保护管理特性模块
      防止它被非授权访问,还要保护这个特性模块内部的那些子路由
      你可以使用canActivateChild
    return this.canActivate(next, state);
  }

  public checkAuth(authName: string): boolean { // 判断是否可以进入页面的相关逻辑
    const hasAuth = this.example.isAuth(authName);
    if (hasAuth) {
      return true;
    }
    this.router.navigate(['/403']);
    return false;
  }
}

 // CanActivate, CanActivateChild如何分别在路由模块中进行使用
 eg: 'CanActivate'
 const routes: Routes = [
  {
    path: '',
    component: ExampleComponent,
    canActivate: [ExampleGuardService],
    data: {
      title: '测试',
    },
  },
];

eg: 'CanActivateChild'
// 同样把这个 ExampleGuardService
   添加到“无组件的”管理路由(无组件路由:"分组路由,而不需要组件, 一个无组件的路由能让守卫子路由变得更容易"),
   来同时保护它的所有子路由,而不是为每个路由单独添加这个 ExampleGuardService。
 const routes: Routes = [
  {
    path: '',
    component: ExampleComponent,
    canActivateChild: [ExampleGuardService],
    children: [
      {
        path: '',
        component: ExampleChildComponent,
        data: { title: 'test' },
        pathMatch: 'full'
      }]
  },
];

CanDeactivate

应用场景: 处理未保存的更改,相当于在离开这个路由的时候触发组件中的相关判断逻辑

// ExampleDetailDeactivateGuard文件
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { ExampleComponent } from '../exampl/exampl.component';

@Injectable()
export class ExampleDetailDeactivateGuard implements CanDeactivate<ExampleComponent> {
  public canDeactivate(
    component: ExampleComponent,
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | boolean {
    return component.canDeactivate(); // 离开当前路由时,相关的判断是否需要保存逻辑放到具体的组件中
  }
}

// ExampleComponent文件
创建了一个 Guard,它将检查这个(任意)组件中是否有 "canDeactivate()" 函数。 ExampleComponent文件就会有这个方法。
但是该守卫并不需要知道ExampleComponent文件确认退出激活状态的详情。 它只需要检查该组件是否有一个 canDeactivate() 方法,并调用它。
这就让该守卫可以复用。
  public canDeactivate(): Observable<boolean> | boolean {
    // 此组件判断是否离开保存的相关逻辑
  }

希望这篇关于Guard的文章可以对各位小哥哥,小姐姐带来些许的帮助哈 😄()~~

相关文章

  • Angular guard 路由守卫的简介

    啥时候会用到路由守卫? 该用户可能无权导航到目标组件。 可能用户得先登录(认证)。 在显示目标组件前,你可能得先获...

  • Angular路由守卫

    引言 在企业应用中权限、复杂页多路由数据处理、进入与离开路由数据处理这些是非常常见的需求。 当希望用户离开一个正常...

  • angular的路由守卫

    what? 路由守卫是保护一个路由对象中的组件,是否被访问如何实现 : 1.创建一个服务 2.配置 service...

  • Angular 监听浏览器事件(刷新/关闭/...)

    在项目中,关于Angular路由跳转的控制(Guard)如果基本都是基于CanActivatee与canDeact...

  • vue的路由守卫

    路由守卫分3种:全局守卫路由独享守卫组件内的路由守卫 1.全局守卫:beforeEachbeforeResolve...

  • 简介angular路由

    angular路由 北京小课堂 分享人:吴昊杰 目录 1.背景介绍 2.知识剖析 3.常见问题 4.解决方案 5....

  • Angular 2+ 路由守卫

    具体逻辑比较简单,就是看要触发的路由是不是在 LocalStorage 里存着。 参考资料: Angular路由守...

  • Angular2路由教程2-使用Guard和Resolve进行验

    Coding I am Angular2路由教程2-使用Guard和Resolve进行验证和权限控制 发表于 2...

  • vue-路由导航守卫&异步组件

    导航守卫包括全局导航守卫、路由守卫、组件局部守卫 全局导航守卫 在全局导航守卫中,每次路由的跳转他们三个都会被触发...

  • 路由守卫

    路由守卫分为三种 全局守卫: 路由独享守卫卸载route里 组件内守卫:写在组件配置对象里

网友评论

      本文标题:Angular guard 路由守卫的简介

      本文链接:https://www.haomeiwen.com/subject/uzytyhtx.html