我有一个非常通用的 Redux(嗯,rxjs-store)结构。基本上,我的数据类型都是称为“元素”的通用数据结构的所有不同版本(每个都由不同的“元素类型”定义)。
目标是当新数据对象出现时,我不必向存储、API、后端、数据库等添加一组全新的数据对象。
到目前为止,这运行良好,但我遇到了 Redux & Reselect 的问题,其中选择器会重新计算多次。
这是一个例子。对于我的页面,我需要加载 4 组特定类型的元素:
// subscribe to data
const elements$ = Observable.combineLatest(
this.elementTypeManager.getElementTypeByName('DistributionNetworkNode'),
this.elementTypeManager.getElementTypeByName('Socket'),
this.elementTypeManager.getElementTypeByName('Area'),
this.elementTypeManager.getElementTypeByName('DemandType'))
.switchMap(nodeAndSocketTypes => Observable.combineLatest(
this.elementManager.getElementsByType(nodeAndSocketTypes[0].id),
this.elementManager.getElementsByType(nodeAndSocketTypes[1].id),
this.elementManager.getElementsByType(nodeAndSocketTypes[2].id),
this.elementManager.getElementsByType(nodeAndSocketTypes[3].id)));
elementTypeManager 和 elementManager 是发送 Redux Action 的服务,并使用 reselect 来查询 store,如下所示:
public getElementsByType(elementTypeId: AAGUID): Observable<Elements> {
// dispatch an action to the store (triggers http and storing data)
this.store.dispatch(this.elementActions.loadElementsForType(elementTypeId));
// use reselect to query store
return this.store.select(getElementsByTypeFactory(elementTypeId));
}
该Load Elements
操作触发一个 http 请求以检索数据,并发出一个Store Elements Data
操作,reducer 将其接收并放入存储中。
重新选择选择器非常简单,如下所示:
export const getElements = (state: AppState) => state.elements;
export function getElementsByTypeFactory(elementTypeId: AAGUID, includeValues: boolean = false) {
return createSelector([getElements],
(elements: Elements) => elements.filter(e => e.elementTypeId === elementTypeId));
}
它接受元素,并按指定类型过滤。
问题是,动作是按顺序调用的:
Load Elements (DistributionNetworkNode)
Load Elements (Socket)
Load Elements (Area)
Load Elements (DemandType)
然后,按顺序存储:
Store Element Data (DistributionNetworkNode)
Store Element Data (Socket)
Store Element Data (Area)
Store Element Data (DemandType)
每次 reducer 将数据放入 store 时,reselect 都会重新计算。当然,它还没有完成所有数据的放入,所以其他选择器返回 0 结果。
结果,我CombineLatest
发出了 4 次,一次只发出DistributionNetworkNode
数据,一次发出DistributionNetworkNode
和Socket
数据,一次发出DistributionNetworkNode
,Socket
和Area
数据等。
这是我的数据结构方式以及我如何使用重新选择的持续问题,我不确定如何在不影响数据结构的通用方式的情况下克服它。
在使用重新选择查询/发送数据之前,如何确保我的所有 Store Element Data 操作都已发生?