我目前正在使用Angular 5应用程序,该应用程序将使用ngrx-store的一些缓存策略,允许用户查看项目并返回主列表而无需再次发出请求。
我使用效果来请求数据并使用reducer根据我的htp响应更新我的全局状态。如您所见,为了成功,会触发RequestPartnersSuccess操作,并且对于错误,会触发RequestPartnersFail。
该物业' internalAppDynamic.searchPartners.recoverLatest'从我的全局状态指示我是否应该从缓存中恢复我的列表,在这种情况下,效果应该返回一个方法,如果'声明并完成我的流程。
@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()类的新实例。
我能做些什么来达到理想的效果?有人能更好地向我解释一下Observables的预期效果吗?
谢谢!
答案 0 :(得分:2)
I was able to achieve the desired behavior by creating an auxiliary observable just to be able to pass my action inside the stream, like this:
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)))
)
}))
If you need to pass your action object inside the stream to use it's type or payload for something else, you should pass it as a auxObservable parameter, like this:
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)))
)
}))
I think someone might need this technique in the future, so I'm sharing my solution =)
If someone can think about a better way to intercept the default stream behavior if a condition is met and trigger a diferent reducer case, please share it with us!
Update:
As Alexander pointed out, the auxObservable is not necessary and it's possible to just return of(new SearchPartnersActions.RequestPartnersRecoverCache()), making sure you imported the 'of' operator from rxjs.
Thanks!