Angular 2 Router Guards 命令
Angular 2 Router Guards order
Angular一个数组可以定义2个router guards。例如:
<code>
canActivate: ['CanAlwaysActivateGuard','AuthGuard']
</code>
以下是我的问题:
- 两名守卫的执行顺序是什么。
- 如果我只想在 CanAlwaysActivateGuard returns 为真时执行 AuthGuard,这是否可能。
what will be the order of execution for both the guards.
它们将运行同步,无需等待对方。
if i want to execute AuthGuard only if CanAlwaysActivateGuard returns
true, would that be possible.
不,当前的实现不可能。作为解决方法,您可以按顺序为 运行 您的守卫创建一个包装守卫。
另请参阅此 。
我遇到了这个问题,在寻找答案时遇到了您的 post。找到 none——今天有时间——我想出了一个你可能感兴趣的解决方案。我创建了一个 "CompositeRouteGuard":
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import {Injectable, Injector} from '@angular/core';
import { Observable } from "rxjs";
@Injectable()
export class CompositeRouteGuard implements CanActivate {
constructor( protected router: Router,
protected injector: Injector ) {
}
canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> {
var compositeCanActivateObservable: Observable<boolean> = Observable.of(true);
let routeGuards = route.data.routeGuards;
if(routeGuards){
for( var i = 0; i < routeGuards.length; i++ ){
let routeGuard = this.injector.get(routeGuards[i]);
let canActivateObservable = routeGuard.canActivate(route, state);
compositeCanActivateObservable = compositeCanActivateObservable.flatMap( (bool) => {
if(!bool){
return Observable.of(false);
}
else{
return canActivateObservable;
}
});
}
}
return compositeCanActivateObservable;
}
}
这需要在您的 routes.ts 中进行一些额外的配置。您需要在路由的数据元素中添加一个 "routeGuards" 数组。
const routes: Routes = [
{
path: '...',
component: AComponent,
data: { routeGuards: [ FooRouteGuard, BarRouteGuard, BazRouteGuard ] },
canActivate: [ CompositeRouteGuard ]
},
...
我只关心 canActivate 操作,但您应该能够轻松扩展它,例如 "canDeactivate"(例如)如果您需要的话。
现在我的路由守卫 运行 "in order" 具有 "and" 语义(所有都必须成功才能激活路由)。
当前版本可以使用child router,例如:
{
path: 'your-path',
canActivate: [
CanAlwaysActivateGuard,
],
canActivateChild: [
AuthGuard,
],
children: [
]
}
你也可以在AuthGuard.canActivate()之前继承守卫运行super.canActivate()
。
In this example canActivate()
method in both classes returns a Promise
.
@Injectable({
providedIn: 'root',
})
class AuthGuard extends CanAlwaysActivateGuard implements CanActivate {
constructor(/*...*/) {
super(/*...*/);
}
async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> {
const result = await super.canActivate(next, state);
if (result === true) { // Check the expected result from the parent
return await this.logicOfYourAuthGuard(); // Run your logic and return it
}
return result; // Return the original result if logic of AuthGuard is not nedded
}
}
然后,在路线中,只使用AuthGuard
。
其他选项是使用 canActivateChild
,因为 canActivate
在 canActivateChild
.
之前守卫 运行s
如果你嵌套它们,你可以决定它们的顺序:
import { Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
canActivate: [CanAlwaysActivateGuard],
children: [
{
path: '',
canActivate: [AuthGuard],
children: [
// (...)
],
}
],
}
];
在任何内部路由守卫之前评估外部路由守卫。
Angular一个数组可以定义2个router guards。例如:
<code>
canActivate: ['CanAlwaysActivateGuard','AuthGuard']
</code>
以下是我的问题:
- 两名守卫的执行顺序是什么。
- 如果我只想在 CanAlwaysActivateGuard returns 为真时执行 AuthGuard,这是否可能。
what will be the order of execution for both the guards.
它们将运行同步,无需等待对方。
if i want to execute AuthGuard only if CanAlwaysActivateGuard returns true, would that be possible.
不,当前的实现不可能。作为解决方法,您可以按顺序为 运行 您的守卫创建一个包装守卫。
另请参阅此
我遇到了这个问题,在寻找答案时遇到了您的 post。找到 none——今天有时间——我想出了一个你可能感兴趣的解决方案。我创建了一个 "CompositeRouteGuard":
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import {Injectable, Injector} from '@angular/core';
import { Observable } from "rxjs";
@Injectable()
export class CompositeRouteGuard implements CanActivate {
constructor( protected router: Router,
protected injector: Injector ) {
}
canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> {
var compositeCanActivateObservable: Observable<boolean> = Observable.of(true);
let routeGuards = route.data.routeGuards;
if(routeGuards){
for( var i = 0; i < routeGuards.length; i++ ){
let routeGuard = this.injector.get(routeGuards[i]);
let canActivateObservable = routeGuard.canActivate(route, state);
compositeCanActivateObservable = compositeCanActivateObservable.flatMap( (bool) => {
if(!bool){
return Observable.of(false);
}
else{
return canActivateObservable;
}
});
}
}
return compositeCanActivateObservable;
}
}
这需要在您的 routes.ts 中进行一些额外的配置。您需要在路由的数据元素中添加一个 "routeGuards" 数组。
const routes: Routes = [
{
path: '...',
component: AComponent,
data: { routeGuards: [ FooRouteGuard, BarRouteGuard, BazRouteGuard ] },
canActivate: [ CompositeRouteGuard ]
},
...
我只关心 canActivate 操作,但您应该能够轻松扩展它,例如 "canDeactivate"(例如)如果您需要的话。
现在我的路由守卫 运行 "in order" 具有 "and" 语义(所有都必须成功才能激活路由)。
当前版本可以使用child router,例如:
{
path: 'your-path',
canActivate: [
CanAlwaysActivateGuard,
],
canActivateChild: [
AuthGuard,
],
children: [
]
}
你也可以在AuthGuard.canActivate()之前继承守卫运行super.canActivate()
。
In this example
canActivate()
method in both classes returns aPromise
.
@Injectable({
providedIn: 'root',
})
class AuthGuard extends CanAlwaysActivateGuard implements CanActivate {
constructor(/*...*/) {
super(/*...*/);
}
async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> {
const result = await super.canActivate(next, state);
if (result === true) { // Check the expected result from the parent
return await this.logicOfYourAuthGuard(); // Run your logic and return it
}
return result; // Return the original result if logic of AuthGuard is not nedded
}
}
然后,在路线中,只使用AuthGuard
。
其他选项是使用 canActivateChild
,因为 canActivate
在 canActivateChild
.
如果你嵌套它们,你可以决定它们的顺序:
import { Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
canActivate: [CanAlwaysActivateGuard],
children: [
{
path: '',
canActivate: [AuthGuard],
children: [
// (...)
],
}
],
}
];
在任何内部路由守卫之前评估外部路由守卫。