angular - Rxjs 链接,怎么做?
问题描述
以下代码是我所拥有的并且它有效。
canActivate(route: ActivatedRouteSnapshot): Observable<UrlTree | boolean> {
return new Observable<UrlTree | boolean>((observer) => {
this._authorizedStore
.select(selectProfile)
.pipe(take(1))
.subscribe((profile) => {
if (!profile) {
this._authorizedStore.dispatch(
AuthorizedActions.loadProfile({ userId: this._authenticationApi.getUser().id }),
);
}
this._authorizedStore
.select(selectAuthorizedState)
.pipe(first((state) => !!state.profile))
.subscribe((state) => {
if (state.profile.profiles.length > 0) {
observer.next(true);
} else {
observer.next(this.router.createUrlTree(['./settings']));
}
observer.complete();
});
});
});
}
我想要的是找出一种更好、更漂亮的方法来做同样的事情。基本上我想先检查我是否有个人资料,如果没有,我想触发请求然后等待。需要注意的一件事,正如您所看到的,我正在使用 Ngrx,所以如果我在开始时不采取(1),我会得到一个无限循环(不是配置文件,发出请求,不是配置文件,发出请求......) .
有任何想法吗?
解决方案
this._authorizedStore
.select(selectProfile)
.pipe(
take(1),
tap(profile => {
if (!profile) {
this._authorizedStore.dispatch(
AuthorizedActions.loadProfile({ userId: this._authenticationApi.getUser().id }),
);
}
}),
switchMap(profile => this._authorizedStore.select(selectAuthorizedState).pipe(first(state => !!state.profile)))
)
.subscribe(state => {
if (state.profile.profiles.length > 0) {
observer.next(true);
} else {
observer.next(this.router.createUrlTree(['./settings']));
}
observer.complete();
});
您还可以将整个代码缩短为:
canActivate(route: ActivatedRouteSnapshot): Observable<UrlTree | boolean> {
return this._authorizedStore
.select(selectProfile)
.pipe(
take(1),
tap(profile => {
if (!profile) {
this._authorizedStore.dispatch(
AuthorizedActions.loadProfile({ userId: this._authenticationApi.getUser().id }),
);
}
}),
switchMap(profile => this._authorizedStore.select(selectAuthorizedState)),
first(state => !!state.profile),
map(state => state.profile.profiles.length > 0 ? true : this.router.createUrlTree(['./settings']))
);
}
推荐阅读
- google-apps-script - 应用脚本基于时间的触发器多次执行
- google-apps-script - 使用脚本编辑器根据特定单元格值自动隐藏“非空”行
- php - Apple 登录二手零售店
- node.js - 将云功能更新为合适的 Node js 版本
- sails.js - 覆盖 Sails.js 水线拦截 Find 方法
- terraform - local-exec 问题并将值传递给它
- c# - 将小数四舍五入到小数点后 2 位
- python - 从高斯分布采样
- arrays - 尝试根据用户输入应用过滤器时无法读取未定义的属性“包含”
- javascript - 角度检测用户是否来自 webview