【发布时间】:2017-04-20 08:25:39
【问题描述】:
我在 Angular 2 应用程序中使用 @ngrx/effects,但在尝试实现依赖于基于应用程序状态的条件的效果时遇到了一些问题。
在我的状态下,我有一张 Location -> Capabilities 地图,以locationId 为键(以及其他 Location -> * 地图)。当ACTION_A 发生时,我只希望它在当前位置具有最新功能时继续。当ACTION_A 被调度时,功能可能已经是最新的,但是,应用程序也可能正在加载新功能。
使用下面的代码,一旦ACTION_A 被调度一次,isOutOfDate 就会在每次 any 动作被调度到商店时被调用。因此,即使在满足最新过滤器之后,observable 似乎仍然处于活动状态。但是,如果 getCapabilities 被 getCapabilitiesWorking 替换,那么 isOutOfDate 只会在每次调度 ACTION_A 操作时满足过滤条件时才被调用,正如我对任一实现所期望的那样。
所以,我似乎错过了 combineLatest 或 filter 或 take 的工作原理......
或者也许我正在接近这一切都错了......
我希望能够为我的“当前位置”选择器使用通用功能
有什么想法吗?
@Effect() route$ = actions$
.ofType(ACTION_A)
.switchMap(() => this._store.let(getCapabilities)
.filter(capabilities => !isOutOfDate(capabilities))
.take(1)
)
.map( do some stuff );
// Selector function that causes excess observable emits
export const getCapabilities =
compose(fromLocations.currentLocationLookup(fromLocations.getCapabilities), fromRoot.getLocations);
// Selector function works as expected
export const getCapabilitiesWorking = function (state$: Observable<AppState>): Observable<Capability> {
return state$
.let(fromRoot.getLocations)
.map(l => l.capabilitiesByLocation[l.currentId]);
};
// fromLocations
// -------------
export function getCapabilities(state$: Observable<LocationsState>): Observable<{ [id: string]: Capability }> {
return state$.map(s => s.capabilitiesByLocation);
}
// Find the value in 'collection' corresponding to the current location
export function currentLocationLookup<T>(
collection: (state$: Observable<LocationsState>) => Observable<{ [id: string]: T }>
): (state$: Observable<LocationsState>) => Observable<T> {
return (state$: Observable<LocationsState>): Observable<T> => {
return Observable.combineLatest(
state$.let(getCurrentLocation),
state$.let(collection),
(locId, map) => map[locId]
);
};
}
编辑:澄清一下,isOutOfDate 函数不断被调用,但是“做一些事情”并没有......
【问题讨论】:
标签: typescript rxjs ngrx