0

我有PolicyGuard一个方法canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)

canActivate我创建了一个 observable 时,在这个 observable 内部我订阅了一个从我的AbilityService.

我从中检索到的 observableAbilityService监听用户“策略”/“能力”的变化。

当我对用户的“策略”进行更改并将这些更改推送到客户端时,这会变得非常混乱,Socket.io当我不希望它使用页面重定向到主页时可能会发生(一个订阅运行obs.next(true)而另一个订阅路由回家并奔跑obs.next(false)

离开订阅的页面时,有没有办法让订阅取消订阅?

@Injectable()
export class PolicyGuard implements CanActivate {

    constructor(protected router: Router, private abilityService: AbilityService) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        console.log("PolicyGuard() - canActivate()");

        return new Observable<boolean>(obs => {
            const observable = this.abilityService.getAbility();
            observable.subscribe(ability => {
                const can = ability.can(route.data.action, route.data.subject);

                if (can) {
                    obs.next(true);
                }
                else {
                    this.router.navigate(['/home']);
                    obs.next(false);
                }
            });
        });
    }
}
4

1 回答 1

0

您当前创建了一个额外的 Observable,我认为这不是必需的。您可以this.abilityService.getAbility()使用 RxJS 运算符简单地返回和转换返回值map。这样 Angular 将接管并处理来自 Observable 的订阅。

这看起来像这样:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  console.log("PolicyGuard() - canActivate()");

  return this.abilityService.getAbility().pipe(
    map(ability => {
      const can = ability.can(route.data.action, route.data.subject);
     
      if (!can) {
        this.router.navigate(['/home']);
      }
      return can;
    });
  );
}

angular.io 上的canActivate 示例做了类似的事情,只是没有map运算符。

于 2021-12-16T19:18:14.080 回答