MST

星途 面试题库

面试题:Angular导航控制与路由守卫链

假设在一个复杂的Angular应用中,存在多个路由守卫,如CanActivate、CanDeactivate、Resolve等,如何合理配置和管理这些路由守卫形成一个有效的守卫链,以确保导航控制的准确性和高效性?并且说明在不同守卫执行过程中如何处理异步操作及错误情况。
49.8万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

合理配置和管理路由守卫形成有效守卫链

  1. CanActivate:用于决定是否可以激活路由。通常放在首位,例如在用户登录验证场景,判断用户是否已登录。在app-routing.module.ts中配置如下:
const routes: Routes = [
  {
    path: 'protected-route',
    component: ProtectedComponent,
    canActivate: [AuthGuard]
  }
];
  1. Resolve:在路由激活之前获取数据。比如在展示商品详情页时,提前获取商品数据。配置方式如下:
const routes: Routes = [
  {
    path: 'product/:id',
    component: ProductComponent,
    resolve: {
      product: ProductResolver
    }
  }
];
  1. CanDeactivate:用于决定是否可以离开当前路由。常用于防止用户未保存表单数据就离开页面。在目标组件所在路由配置:
const routes: Routes = [
  {
    path: 'edit-form',
    component: EditFormComponent,
    canDeactivate: [CanDeactivateGuard]
  }
];
  1. 守卫链顺序:一般按照CanActivate -> Resolve -> CanDeactivate(离开当前路由时)的顺序执行。在配置路由时,确保各个守卫按此逻辑顺序添加。

处理异步操作及错误情况

  1. 异步操作处理
    • CanActivate和Resolve:这两个守卫可以返回Observable<boolean>Promise<boolean>来处理异步操作。例如,在AuthGuardcanActivate方法中进行异步登录验证:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { map, take } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.authService.isLoggedIn.pipe(
      take(1),
      map((isLoggedIn: boolean) => {
        if (!isLoggedIn) {
          this.router.navigate(['/login']);
          return false;
        }
        return true;
      })
    );
  }
}
- **CanDeactivate**:同样可以返回`Observable<boolean>`或`Promise<boolean>`。例如在`EditFormComponent`离开时,提示用户保存表单:
import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { EditFormComponent } from './edit-form.component';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<EditFormComponent> {
  canDeactivate(
    component: EditFormComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    if (component.isFormDirty) {
      return window.confirm('你有未保存的数据,确定离开吗?');
    }
    return true;
  }
}
  1. 错误情况处理
    • CanActivate和Resolve:如果异步操作失败,例如AuthGuard中登录验证失败,可以通过Router服务导航到错误页面或登录页面。如上述AuthGuard示例中,验证失败导航到/login
    • CanDeactivate:如果用户选择不离开(返回false),则保持在当前路由。如果出现错误(如异步操作异常),可以通过console.error记录错误,并返回false阻止离开,同时可以弹出提示框告知用户。