Angular 从入坑到挖坑 - 路由守卫连连看 (3)

使用 CanActivateChild 完成对于子路由的认证授权

4.2.3、CanDeactivate:处理用户未提交的修改

当进行表单填报之类的操作时,因为会涉及到一个提交的动作,当用户没有点击保存按钮就离开时,最好能暂停,对用户进行一个友好性的提示,由用户选择后续的操作

创建一个路由守卫,继承于 CanDeactivate 接口

ng g guard hero-list/guards/hero-can-deactivate

与上面的 CanActivate、CanActivateChild 路由守卫的使用方式不同,对于 CanDeactivate 守卫来说,我们需要将参数中的 unknown 替换成我们实际需要进行路由守卫的组件

import { Injectable } from '@angular/core'; import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class HeroCanDeactivateGuard implements CanDeactivate<unknown> { canDeactivate( component: unknown, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { return true; } }

例如,这里针对的是 HeroListComponent 这个组件,因此我们需要将泛型的参数 unknown 改为 HeroListComponent,通过 component 参数,就可以获得需要进行路由守卫的组件的相关信息

import { Injectable } from '@angular/core'; import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, } from '@angular/router'; import { Observable } from 'rxjs'; // 引入需要进行路由守卫的组件 import { HeroListComponent } from '../hero-list.component'; @Injectable({ providedIn: 'root', }) export class HeroCanDeactivateGuard implements CanDeactivate<HeroListComponent> { canDeactivate( component: HeroListComponent, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot ): | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { // 判断是否修改了原始数据 // const data = component.hero; if (data === undefined) { return true; } const origin = component.heroList.find(hero => hero.id === data.id); if (data.name === origin.name) { return true; } return window.confirm('内容未提交,确认离开?'); } }

这里模拟判断用户有没有修改原始的数据,当用户修改了数据并移动到别的页面时,触发路由守卫,提示用户是否保存后再离开当前页面

使用 CanDeactivate 处理用户未提交的修改

4.3、异步路由 4.3.1、惰性加载

当应用逐渐扩大,使用现有的加载方式会造成应用在第一次访问时就加载了全部的组件,从而导致系统首次渲染过慢。因此这里可以使用惰性加载的方式在请求具体的模块时才加载对应的组件

惰性加载只针对于特性模块(NgModule),因此为了使用惰性加载这个功能点,我们需要将系统按照功能划分,拆分出一个个独立的模块

首先通过 Angular CLI 创建一个危机中心模块(crisis 模块)

-- 查看创建模块的相关参数 ng g module --help -- 创建危机中心模块(自动在 app.moudule.ts 中引入新创建的 CrisisModule、添加当前模块的路由配置) ng g module crisis --module app --routing

将 crisis-list、crisis-detail 组件全部移动到 crisis 模块下面,并在 CrisisModule 中添加对于 crisis-list、crisis-detail 组件的声明,同时将原来在 app.module.ts 中声明的组件代码移除

import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { CrisisRoutingModule } from './crisis-routing.module'; import { FormsModule } from '@angular/forms'; // 引入模块中使用到的组件 import { CrisisListComponent } from './crisis-list/crisis-list.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component'; @NgModule({ declarations: [ CrisisListComponent, CrisisDetailComponent ], imports: [ CommonModule, FormsModule, CrisisRoutingModule ] }) export class CrisisModule { }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspggy.html