mal*_*kan 5 observable rxjs angular angular-router-guards angular-observable
我正在尝试Angular2+使用来自共享服务的 Observable创建一个路由保护,该服务保存当前用户角色的字符串值。
问题显然在于将我的注意力从 Promises 转移到 Observables。
到目前为止,我所做的都是基于启发式和尝试错误的方法,但我通过杀死浏览器来解决问题感谢 danday74
.
借助相当于promise.then()的RxJS 序列?我已经将我想做的事情翻译成这个链:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
如果 ,如何停止可观察链的进一步传播isRoleAuthenticated = true?如果满足此类条件,我需要返回该布尔值,并确保.do之后不调用运算符块。
限制是必须从canActivate警卫返回布尔值。
无论您从第一个 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
})
Run Code Online (Sandbox Code Playgroud)
另外,您正在使用 RxJs v5 语法,但应该使用 v6。在 v6 中,运算符 - mergeMap、tap、map - 在管道中以逗号分隔。
可能是路由器导航阻止了最终返回并导致挂起?评论出来,看看它是否会停止挂起。
不确定这是否能完全解决您的问题,但希望能为凌晨 1 点提供一些有用的见解
我假设这些返回 Observables:
如果他们不这样做,你就会遇到问题。
您可以创建一个由沿途收集的 Observables 结果组成的对象,并将其进一步传播,从而解决问题,而不是专注于停止链:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7279 次 |
| 最近记录: |