介绍
我正在尝试使用共享服务中的Observable在Angular2+
中创建路由保护,该服务保留了当前用户 Angular 色的字符串值。
问题显然出在我的思维从应许转向可观察。
。
尝试(由于@ danday74而得到改进)
在RxJS sequence equvalent to promise.then()?的帮助下,我已经将我想做的事情翻译成以下内容:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
return this.auth.isRoleAuthenticated(route.data.roles)
.mergeMap((isRoleAuthenticated: boolean) => {
return isRoleAuthenticated ? Observable.of(true) : this.auth.isRole(Roles.DEFAULT_USER);
})
.do((isDefaultUser: boolean) => {
const redirectUrl: string = isDefaultUser ? 'SOMEWHERE' : 'SOMEWHERE_ELSE';
this.router.navigate([redirectUrl]);
})
.map((isDefaultUser: boolean) => {
return false;
});
}
问题
如果使用
isRoleAuthenticated = true
,如何停止可观察链的进一步传播?如果满足这样的条件,我需要返回该 bool 值,并确保之后不调用.do
运算符块。限制是必须从
canActivate
Guard返回 bool 值。 最佳答案
从第一个mergeMap返回的任何内容都会传递到第二个mergeMap,这样它就不会停止进一步传播。如果要停止传播,请使用过滤器(尽管在这种情况下可能会导致挂起)。
仅在返回Observable时才使用mergeMap,但无需从第二个mergeMap返回Observable。做就是了:
.mergeMap((isRoleAuthenticated: boolean) => {
if (isRoleAuthenticated) {
return Observable.of(true)
}
return this.auth.isRole(Roles.DEFAULT_USER)
})
.tap((isDefaultUser: boolean) => {
if (isDefaultUser) {
this.router.navigate(['SOMEWHERE'])
} else {
this.router.navigate(['SOMEWHERE_ELSE'])
}
})
.map((isDefaultUser: boolean) => {
return false
})
另外,您正在使用RxJs v5语法,但应使用v6。在v6中,运算符-mergeMap,tap,map-用逗号分隔在管道中。路由器导航是否有可能阻止最终返回并导致挂起?注释掉它,看看它是否可以停止挂起。
不确定是否可以完全解决您的问题,但希望凌晨1点有一些有用的见解
我假设这些返回Observables:
如果他们不这样做,您将遇到问题。
解决方案
与其专注于停止链,不如创建一个由收集的Observable的结果组成的对象,并将其进一步传播,从而解决了问题:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
return this.auth.getRole()
.mergeMap((role: string) => {
return this.auth.isRoleAuthorized(route.data.roles)
.map((authorized: boolean) => ({
role: role,
authorized: authorized
}));
})
.do((markers: { role: string, authorized: boolean }) => {
const redirectUrl: string = markers.role === Roles.DEFAULT_USER ? 'SOMEWHERE' : 'SOMEWHERE_ELSE';
this.router.navigate([redirectUrl]);
})
.map((markers: { role: string, authorized: boolean }) => {
return markers.authorized;
});
}
关于angular - 如果满足某些条件,RXJS停止可观察链的传播,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52845192/