我正在尝试使用共享服务中的Observable在self.filteredReasons = ko.computed(function() {
return ko.utils.arrayFilter(self.Reasons(), function(reason) {
if(reason.Id !== 1) {
return true;
}
});
});
中创建路由保护,该服务保留了当前用户角色的字符串值。
问题显然出在我的思维从应许转向可观察。
到目前为止,我所做的是基于启发式和尝试与错误方法,但是 我杀死了浏览器感谢danday74
。
在RxJS sequence equvalent to promise.then()?的帮助下,我已经将我想做的事情翻译成该链:
<select data-bind="options: filteredReasons , optionsText: 'Title', optionsValue: 'Id', value: SelectReason, optionsCaption: 'Choose..'"></select>
如果Angular2+
,如何停止可观察链的进一步传播?如果满足这样的条件,我需要返回该布尔值,并确保之后不调用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
后卫返回布尔值。
答案 0 :(得分:1)
您从第一个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;
});
}
答案 1 :(得分:1)
do()
运算符仅适用于next
通知,因此,如果您不想处理.mergeMap
之后的内容,可以使用filter()
进行过滤:< / p>
return this.auth.isRoleAuthenticated(route.data.roles)
.mergeMap((isRoleAuthenticated: boolean) => {
return isRoleAuthenticated ? Observable.of(true) : this.auth.isRole(Roles.DEFAULT_USER);
})
.filter(authenticated => authenticated !== true)
但是,您似乎可以只返回Observable.empty()
而不是Observable.of(true)
,因为这只会发出complete
通知,没有next
项,因此没有任何内容传递给do()
:
.mergeMap((isRoleAuthenticated: boolean) => {
return isRoleAuthenticated ? Observable.empty() : this.auth.isRole(Roles.DEFAULT_USER);
})
答案 2 :(得分:0)
您可以返回Observable.of(true)
而不是返回Observable.empty()
,它会完成而不会发出任何值。因此不会执行以下链。