当进行表单填报之类的操作时,因为会涉及到一个提交的动作,当用户没有点击保存按钮就离开时,最好能暂停,对用户进行一个友好性的提示,由用户选择后续的操作
创建一个路由守卫,继承于 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('内容未提交,确认离开?'); } }这里模拟判断用户有没有修改原始的数据,当用户修改了数据并移动到别的页面时,触发路由守卫,提示用户是否保存后再离开当前页面
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 { }