Angular 路由守卫

1. 路由

Angular路由: 可以控制页面跳转;可以在多视图间切换;

2. 路由守卫

Angular路由守卫: 在进入或离开某路由时,用于判断是否可以离开、进入某路由;;; return true 代表可以进入当前路由;return false 代表不可以进入当前路由,但可以进入自定义的路由;

3. 路由守卫与路由的关系

路由守卫只只能应用于路由项上;路由守卫可以应用于多个路由项;每个路由项也可以有多个路由守卫;

路由守卫通过实现如下接口来操作:

  • canActivate: 控制是否允许进入路由。(通过return true/false决定)
  • canActivateChild: 等同 canActivate,只不过针对是所有子路由。
  • canDeactivate: 控制是否允许离开路由。
  • canLoad: 控制是否允许延迟加载整个模块。

4. 什么情况下,路由项上需要配置路由守卫属性

当需要某些条件/某个身份才能进入的路由,这时需要在路由项上加入路由守卫属性

5. 路由守卫的使用 (本例主要实现根据不同身份进入不同路由)

第一步: guard.service.ts - 定义路由守卫文件
  • 第一种写法: 返回Promise对象

@Injectable()
export class GuardService implements CanActivate {
  constructor(private router: Router, private _http: HttpClient) {
  }
  getIsAdmin() {
    return new Promise((resolve) => {
      this._http.get('/user/isAdmin').subscribe((resp: boolean) => {
        resolve(resp);
      });
    });
  }
  // 进入路由守卫
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      return this.getIsAdmin().then((isAdmin) => {
        if (isAdmin) { // 如果是管理员, 可以进入当前路由;
           return true;
        } else {

            // 如果不是管理员,不能进入当前路由,进入手动导航的ordinary路由;
            this.router.navigateByUrl('/ordinary');
            return false;
        }
      });
  }
}

  • 第二种写法: 返回Observable对象

@Injectable()
export class GuardService implements CanActivate {
  constructor(private router: Router, private _http: HttpClient) {
  }
  
  // 进入路由守卫
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      return this._http.get('/user/isAdmin').map((isAdmin) => {
        if (isAdmin) { // 如果是管理员, 可以进入当前路由;
           return true;
        } else {

            // 如果不是管理员,不能进入当前路由,进入手动导航的ordinary路由;
            this.router.navigateByUrl('/ordinary');
            return false;
        }
      });
  }
}

第二步: app.module.ts - 注册路由文件

@NgModule({
  declarations: [AppComponent],
  providers: [
    GuardService
  ],
  bootstrap: [AppComponent]
})

第三步: app.routing.ts - 给对应的路由项配置路由守卫

// 当导航到front时,需要进入路由守卫的canActivate类进行判断是否可以进入此路由

// 什么时候需要在路由项上加路由守卫??当需要某些条件/某个身份才能进入的路由,这时需要在路由项上加入路由守卫属性

export const routes: Routes = [
  {
    path: '',
    component: AppComponent,
    children: [
      {path: '', redirectTo: 'front', pathMatch: 'full'},
      {path: 'front', component: FrontendComponent, canActivate: [GuardService]},
      {path: 'ordinary', component: OrdinaryComponent}
    ]
  },
];
@NgModule({
  imports: [RouterModule.forRoot(routes, {useHash: true})],
  exports: [RouterModule]
})
export class RoutingModule {
}