如何 return 来自路由器事件订阅的路由守卫值

How to return value for route guard from router event subscription

我正在尝试实现基于用户权限的安全路由。没有特定权限的用户无法访问该路由。这就是为什么我在路由中传递正确的名称(惰性模块路由)。但是,我发现获取惰性路由数据有点复杂。我必须订阅路由器事件。但是,在订阅之后,我找不到 return false 或 canactivate true 的方法。

这是我的 canActivate 代码:

 canActivate() {
    this.router.events
      .pipe(
        filter((event) => event instanceof NavigationEnd),
        map(() => this.activatedRoute),
        map((route) => {
          while (route.firstChild) {
            route = route.firstChild;
          }
          return route;
        }),
        mergeMap((route) => route.data))
      .subscribe((event) => {
        const right = event.right; // getting the right name from the route data. 
        const rights = this.localStorageService.getLocalStorageItem('rights');

        if (right) {
          if (rights.includes(right)) {
            // I need to return true from here 
          } else {
            // I need to return false from here 
          }
        }
      });
  }

而且,这是我的路线代码:

const routes: Routes = [{ path: ':id', component: ProfileComponent, 
data: { right: 'VIEW_PROFILE' }, canActivate: [RightRouteGuardService]}];

一个Angular路卫可以returnObservable<boolean> | Promise<boolean> | boolean。我想你想要 return 一个布尔值,但如果在这种情况下我是你,我会 return Observable<boolean>.

试试这个:

canActivate(): Observable<boolean> {
  return this.router.events
      .pipe(
        filter((event) => !!event), // !! add this filter !!
        filter((event) => event instanceof NavigationEnd),
        map(() => this.activatedRoute),
        map((route) => {
          while (route.firstChild) {
            route = route.firstChild;
          }
          return route;
        }),
        mergeMap((route) => route.data),
        // map will return true false for us
        map(event => {
          const right = event.right; // getting the right name from the route data. 
          const rights = this.localStorageService.getLocalStorageItem('rights');
          if (right) {
            if (rights.includes(right)) {
              return true;
            } else {
              return false;
            }
          }
        }),
      );
}

您不再需要订阅,只需从这个 observable 发出的第一个发射就会 return 为您判断真假。

=========================编辑=================== ======= 不要注入路由器并监听事件,因为路由器还没有完成导航,你的 filterNavigationEnd 将不允许它继续进行,因为当时没有事件.

我已经解决了这个问题:

import { Injectable } from "@angular/core";
import {
  ActivatedRouteSnapshot,
  CanActivate,
  RouterStateSnapshot
} from "@angular/router";

@Injectable({
  providedIn: "root"
})
export class RightRouteGuardService implements CanActivate {
  constructor() {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean{
    let right = route.data.right;
    console.log({ right });
    const rights = ['VIEW_STUDENT'];
    if (rights.includes(right)) {
      return true;
    } else {
      return false;
    }
  }
}

canActivate 方法有两个属性,您可以使用这些属性读取相关路由的数据 属性。

我受到了启发post