Angular 角度RxJS-防护罩不';看不到服务中可观察到的更新值
我有一个“onboarding”页面,该页面应该由用户填写一次,并在db中将“passedOnboarding”标志设置为“true” 提交表单后,它应该将用户重定向到其仪表板页面 “仪表板”页面位于一个警卫的后面,该警卫确保用户填写了入职表格,如果用户没有填写,则将其重定向回该页面 我有一个可以观察到的Angular 角度RxJS-防护罩不';看不到服务中可观察到的更新值,angular,rxjs,observable,reactive,Angular,Rxjs,Observable,Reactive,我有一个“onboarding”页面,该页面应该由用户填写一次,并在db中将“passedOnboarding”标志设置为“true” 提交表单后,它应该将用户重定向到其仪表板页面 “仪表板”页面位于一个警卫的后面,该警卫确保用户填写了入职表格,如果用户没有填写,则将其重定向回该页面 我有一个可以观察到的accountDetails$,如下所示: refreshAccountDetails$ = new BehaviorSubject <void> (null); accountD
accountDetails$
,如下所示:
refreshAccountDetails$ = new BehaviorSubject <void> (null);
accountDetails$ = this.refreshAccountDetails$.pipe(
distinctUntilChanged(),
switchMap(() => this.getAccountDetails()),
shareReplay());
以下是Onboard函数,您可以看到,在提交表单后,我尝试刷新accountDetails$
,
以便警卫“查看”更新的详细信息,并允许导航到“仪表板”:
onboarding(request: OnboardingRequest): Observable<ClientDetailsResponse> {
return this.http.postTyped<ClientDetailsResponse>(this.ONBOARDING_ENDPOINT, request).pipe(
tap(() => {
this.refreshAccountDetails$.next(null);
})
);
}
问题是,警卫“看到”了旧的值,其中没有设置标志,因此它重定向回入职页面
我不确定是否accountDetail$
可观察及其源设置正确,或者是否有其他错误
谢谢
canActivate
必须返回一个布尔值,可能您只需要强制强制转换this.router.parseUrl(\u OnboardingPath)
?,类似于this.router.parseUrl(\u OnboardingPath)?true | false
?@Motassem在angular的最新版本中,您还可以返回其他类型,如Observable、Promises和我使用的UrlTree。如果返回UrlTree,它将重定向到该url。如果多个守卫返回UrlTree,则有一个优先级机制。(parseUrl是一个函数,它接受字符串并将其转换为UrlTree)非常有用!我的评论与你的问题无关,但是我想指出,在另一个订阅中订阅不是一个好情况。您应该看看mergeMap和switchMap。使用这些RxJS运算符,您可以将submitForm方法减少为仅一个订阅谢谢@Ruben我没注意到。。我知道switchMap和mergeMap。最后你知道了吗?
onboarding(request: OnboardingRequest): Observable<ClientDetailsResponse> {
return this.http.postTyped<ClientDetailsResponse>(this.ONBOARDING_ENDPOINT, request).pipe(
tap(() => {
this.refreshAccountDetails$.next(null);
})
);
}
export class OnboardingRequiredGuard implements CanActivate {
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.userService.accountDetails$.pipe(
map(accountDetails => {
if (!accountDetails.isOnboardingFilled) {
return this.router.parseUrl(_OnboardingPath_);
}
return true;
})
);
}
}