我目前正在开发一个 Angular 5 应用程序,该应用程序将使用一些缓存策略与 ngrx-store,以允许用户查看项目并返回到主列表,而无需再次发出请求。
我正在使用 Effect 请求数据,并使用 reducer 根据我的 htp 响应更新我的全局状态。如您所见,成功时会触发 RequestPartnersSuccess 操作,错误时会触发 RequestPartnersFail。
我的全局状态中的属性“internalAppDynamic.searchPartners.recoverLatest”指示我是否应该从缓存中恢复我的列表,在这种情况下,效果应该在这个“if”语句中返回一个方法并完成我的流。
@Effect()
loadPartners$ = this.actions$
.ofType(SearchPartnersActions.REQUEST_PARTNERS)
.withLatestFrom(this.store$, (action, state) => {
action = Object.assign(action, {recoverLatest: state.internalAppDynamic.searchPartners.recoverLatest})
return action
})
.pipe(switchMap((action: any) => {
if (action.recoverLatest) {
return new SearchPartnersActions.RequestPartnersRecoverCache()
}
return this.internalPartnersService.getPartners(action.payload).pipe(
map(partners => new SearchPartnersActions.RequestPartnersSuccess(partners)),
catchError(error => of(new SearchPartnersActions.RequestPartnersFail(error)))
)
}))
这是我服务中的 getPartners() 函数:
getPartners (body): Observable<any> {
return this.http
.post(this._baseUrl + 'internal-app/get-partners', body, this.httpOptions)
.pipe(catchError((error: any) => this.errorHandler(error)))
}
问题是我找不到实现此结果的方法。我是 rxjs 和 Observables 的新手,我认为 switchMap 运算符需要另一种返回,而不是我的 SearchPartnersActions.RequestPartnersRecoverCache() 类的新实例。
我该怎么做才能达到预期的结果?有人能更好地向我解释一下这个 Observable 流的预期结果吗?
谢谢!
最佳答案
我能够通过创建一个辅助可观察对象来实现所需的行为,以便能够在流中传递我的操作,如下所示:
auxObservable () {
return Observable.create((observer) => {
observer.next()
})
}
@Effect()
loadPartners$ = this.actions$
.ofType(SearchPartnersActions.REQUEST_PARTNERS)
.withLatestFrom(this.store$, (action, state) => {
action = Object.assign(action, {recoverLatest: state.internalAppDynamic.searchPartners.recoverLatest})
return action
})
.pipe(switchMap((action: any) => {
if (action.recoverLatest) {
return this.auxObservable().pipe(
map(res => new SearchPartnersActions.RequestPartnersRecoverCache())
)
}
return this.internalPartnersService.getPartners(action.payload).pipe(
map(partners => new SearchPartnersActions.RequestPartnersSuccess(partners)),
catchError(error => of(new SearchPartnersActions.RequestPartnersFail(error)))
)
}))
如果您需要在流中传递您的操作对象以将其类型或负载用于其他用途,您应该将其作为 auxObservable 参数传递,如下所示:
auxObservable (action) {
return Observable.create((observer) => {
observer.next(action)
})
}
@Effect()
loadPartners$ = this.actions$
.ofType(SearchPartnersActions.REQUEST_PARTNERS)
.withLatestFrom(this.store$, (action, state) => {
action = Object.assign(action, {recoverLatest: state.internalAppDynamic.searchPartners.recoverLatest})
return action
})
.pipe(switchMap((action: any) => {
if (action.recoverLatest) {
return this.auxObservable(action).pipe(
map(res => new SearchPartnersActions.RequestPartnersRecoverCache())
)
}
return this.internalPartnersService.getPartners(action.payload).pipe(
map(partners => new SearchPartnersActions.RequestPartnersSuccess(partners)),
catchError(error => of(new SearchPartnersActions.RequestPartnersFail(error)))
)
}))
我认为将来有人可能需要这种技术,所以我分享我的解决方案 =)
如果有人可以想出更好的方法来在满足条件时拦截默认流行为并触发不同的 reducer case,请与我们分享!
更新:
正如 Alexander 所指出的,auxObservable 不是必需的,并且可以只返回 of(new SearchPartnersActions.RequestPartnersRecoverCache()),确保您从 rxjs 导入了“of”运算符。
谢谢!
关于angular - Ngrx 效果 : Conditionally return action inside switchMap instead of http response,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49949065/