繁体   English   中英

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

[英]How can you use Angular's canActivate to negate the result of a guard?

canActivate的Angular文档 canActivate ,如果canActivate函数最终返回true ,那么你似乎只能使用canActivate防护来允许继续进行路由。

有没有办法说,“只有在canActivate类评估为false时才进入这条路线”?

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

export const routes: Route[] = [
    { path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },

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

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!

你问题中有趣的是配方:

有没有办法说,“只有在canActivate类评估为false时才进入这条路线”?

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

{ path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },

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

让我们考虑UserLoggedInGuard的以下实现:

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

   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this._authService.isLoggedIn();
    }
} 

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

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

   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return !this._authService.isLoggedIn();
    }
}

现在,方法还可以,但与UserLoggedInGuard的(内部)实现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);
  }
}

现在这正是你所表达的

canActivate: [ !UserLoggedInGuard ]

最好的部分:

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

考虑到您的问题,一种解决方案可能是实现一个反向执行逻辑的路由保护。

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

@Injectable()
export class MyGuard implements CanActivate {

    constructor(private myService: MyService) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        return this.myService.isNotLoggedIn(); //if user not logged in this is true
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM