你如何使用Angular的canActivate来否定守卫的结果?

Cod*_*ein 13 typescript angular-routing canactivate angular angular-guards

从角文档canActivate,看来你只能用canActivate后卫,让程序的途径,如果该canActivate函数返回最后true.

有没有办法说,"只有在canActivate课程评估为false" 时才进入这条路线?"

例如,为了不允许登录用户访问登录页面,我尝试了这个但是它不起作用:

export const routes: Route[] = [
    { path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },
Run Code Online (Sandbox Code Playgroud)

我在控制台中遇到此错误:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError[false]: 
  StaticInjectorError[false]: 
    NullInjectorError: No provider for false!
Error: StaticInjectorError[false]: 
  StaticInjectorError[false]: 
    NullInjectorError: No provider for false!
Run Code Online (Sandbox Code Playgroud)

Jot*_*edo 8

您的问题中有趣的是公式:

是否有某种方式可以说:“如果canActivate类的值为false,则仅继续执行此路由 ”?

以及您如何表达“直观”解决方案:

{ path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },
Run Code Online (Sandbox Code Playgroud)

基本上说,你需要negate的结果UserLoggedInGuard@canActivate

让我们考虑以下的实现UserLoggedInGuard

@Injectable()
export class UserLoggedInGuard implements CanActivate {
   constructor(private _authService: AuthService) {}

   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this._authService.isLoggedIn();
    }
} 
Run Code Online (Sandbox Code Playgroud)

接下来,让我们看看@Mike提出的解决方案

@Injectable()
export class NegateUserLoggedInGuard implements CanActivate {    
    constructor(private _authService: AuthService) {}

   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return !this._authService.isLoggedIn();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,该方法尚可,但与的(内部)实现紧密相关UserLoggedInGuard。如果由于某种原因执行UserLoggedInGuard@canActivate更改,NegateUserLoggedInGuard将中断。

我们如何避免这种情况?简单的滥用依赖注入:

@Injectable()
export class NegateUserLoggedInGuard implements CanActivate {    
  constructor(private _userLoggedInGuard: UserLoggedInGuard) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
     return !this._userLoggedInGuard.canActivate(route,state);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,这正是您所表达的

canActivate: [ !UserLoggedInGuard ]
Run Code Online (Sandbox Code Playgroud)

最好的部分是:

  • 它与内部实施并没有紧密结合 UserLoggedInGuard
  • 可以扩展以操纵多个Guard类的结果

  • 然而,当“isLoggedIn”方法返回 Observable 时,这不起作用 (3认同)