Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何使用角度';s可以激活以否定守卫的结果吗?_Angular_Typescript_Angular Routing_Canactivate_Angular Guards - Fatal编程技术网

Angular 如何使用角度';s可以激活以否定守卫的结果吗?

Angular 如何使用角度';s可以激活以否定守卫的结果吗?,angular,typescript,angular-routing,canactivate,angular-guards,Angular,Typescript,Angular Routing,Canactivate,Angular Guards,在canActivate上,似乎只有当canActivate函数最终返回true时,才可以使用canActivate防护来允许继续执行路由 是否有某种方式可以说,“只有当canActivate类的计算结果为false时,才继续执行此路由?” 例如,为了不允许登录用户访问登录页面,我尝试了以下方法,但无效: export const routes: Route[] = [ { path: 'log-in', component: LoginComponent, canActivate: [

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!

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

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
    }
}

你问题中有趣的是公式:

是否有某种方式可以说,“只有在 canActivate类的计算结果为false

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

{ path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },
基本上就是说,你需要否定
UserLoggedInGuard@canActivate

让我们考虑下面的代码< UsLogLogdEnguld< /C> >:

@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@canActivate
更改,
否定日志保护将中断

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

@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
    类的结果

我遇到了一个类似的问题-想要创建一个只有在未经身份验证的情况下才可访问的登录页面,以及一个只有在经过身份验证的情况下才可访问的仪表板(并自动将用户重定向到相应的页面)。我通过使警卫本身登录+路由敏感来解决这个问题:

路线:

const appRoutes: Routes = [
  { path: 'login', component: LoginComponent, canActivate: [AuthGuard] },
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
卫兵:

export class AuthGuard implements CanActivate {

  private login: UrlTree;
  private dash: UrlTree;

  constructor(private authSvc: AuthenticationService, private router: Router ) {
    this.login = this.router.parseUrl('login');
    this.dash = this.router.parseUrl('dashboard');
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree {
    if (this.authSvc.isSignedIn()) {
      if (route.routeConfig.path === 'login') {
        return this.dash;
      } else {
        return true;
      }
    } else {
      if (route.routeConfig.path === 'login') {
        return true;
      } else {
        return this.login;
      }
    }
  }
}

所以基本上是为
而不是
的情况创建一个完全独立的防护吗?@CodyBugstein正是因为你想要反向,这就是我现在使用的解决方案。但这不是一个理想的解决方案,因为我将不得不加倍我的守卫数量,并有大量重复的代码。这是没有办法的,伙计:(除非你想在服务中创建一个bool
isNotLoggedIn
并用它来评估你的正常防护?不确定你的意思你不能否定一个类型,这对于登录页面的这种特殊情况来说是完全错误的。我创建了一个完全独立的防护,类似于检查用户是否登录的
authrirectguard
)。如果为true,则重定向到登录页,否则继续登录。好主意。我还将把两个导出的类放在同一个文件中,并可能使实际的
canActivate
函数定义成为它们之间的一个单独的通用外部函数。我真的看不到通过函数共享实现的好理由。我只会使用DI为了编写这个否定保护包装器,我也不建议将两个类都放在一个文件中。如果否定保护现在否定了多个保护的结果会怎样?你会将它放在哪个文件中?完美的答案!但是,当“isLoggedIn”方法返回一个可观察的