2

我有一个非常通用的 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数据,一次发出DistributionNetworkNodeSocket数据,一次发出DistributionNetworkNode,SocketArea数据等。

这是我的数据结构方式以及我如何使用重新选择的持续问题,我不确定如何在不影响数据结构的通用方式的情况下克服它。

在使用重新选择查询/发送数据之前,如何确保我的所有 Store Element Data 操作都已发生?

4

0 回答 0