[英]How can you use Angular's canActivate to negate the result of a guard?
From the Angular documentation on canActivate
, it seems you can only use canActivate
guards to allow proceeding to a route if the canActivate
function ultimately returns true
. 从
canActivate
上的Angular文档 canActivate
,如果canActivate
函数最终返回true
,那么你似乎只能使用canActivate
防护来允许继续进行路由。
Is there some way to say, "only proceed to this route if the canActivate
class evaluates to false
" ? 有没有办法说,“只有在
canActivate
类评估为false
时才进入这条路线”?
For example, to not allow logged in users to visit the log in page, I tried this but it did not work: 例如,为了不允许登录用户访问登录页面,我尝试了这个但是它不起作用:
export const routes: Route[] = [
{ path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },
I got this error in the console: 我在控制台中遇到此错误:
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!
The interesting thing in your question is the formulation: 你问题中有趣的是配方:
Is there some way to say, "only proceed to this route if the canActivate class evaluates to false " ?
有没有办法说,“只有在canActivate类评估为false时才进入这条路线”?
And how you expressed the "intuitive" solution: 以及您如何表达“直观”的解决方案:
{ path: 'log-in', component: LoginComponent, canActivate: [ !UserLoggedInGuard ] },
Which basically says, you need to negate
the result of UserLoggedInGuard@canActivate
基本上说,你需要
negate
UserLoggedInGuard@canActivate
的结果
Lets consider the following implementation of the UserLoggedInGuard
: 让我们考虑
UserLoggedInGuard
的以下实现:
@Injectable()
export class UserLoggedInGuard implements CanActivate {
constructor(private _authService: AuthService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this._authService.isLoggedIn();
}
}
Next, lets look at the solution proposed by @Mike 接下来,让我们看看@Mike提出的解决方案
@Injectable()
export class NegateUserLoggedInGuard implements CanActivate {
constructor(private _authService: AuthService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return !this._authService.isLoggedIn();
}
}
Now, the approach is ok, but is tightly coupled to the (internal) implementation of UserLoggedInGuard
. 现在,方法还可以,但与
UserLoggedInGuard
的(内部)实现UserLoggedInGuard
。 If for some reason the implementation of UserLoggedInGuard@canActivate
changes, NegateUserLoggedInGuard
will break. 如果由于某种原因
UserLoggedInGuard@canActivate
的实现发生变化, NegateUserLoggedInGuard
将会中断。
How can we avoid that? 我们怎么能避免这种情况? Simple, abuse dependency injection:
简单的滥用依赖注入:
@Injectable()
export class NegateUserLoggedInGuard implements CanActivate {
constructor(private _userLoggedInGuard: UserLoggedInGuard) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return !this._userLoggedInGuard.canActivate(route,state);
}
}
Now this is doing exactly what you expressed with 现在这正是你所表达的
canActivate: [ !UserLoggedInGuard ]
And the best part: 最好的部分:
UserLoggedInGuard
UserLoggedInGuard
的内部实现紧密结合 Guard
class Guard
类的结果 Thinking about your problem, one solution could be to implement a route guard that does the logic in reverse. 考虑到您的问题,一种解决方案可能是实现一个反向执行逻辑的路由保护。
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.