如何控制ngrx-store选择器的评估?

时间:2018-02-06 20:15:38

标签: ngrx-store ngrx-entity

我有一个选择器:

const mySelector = createSelector(
  selectorA,
  selectorB,
  (a, b) => ({
    field1: a.field1,
    field2: b.field2
  })
)

我知道选择器会在任何输入发生变化时进行评估。

在我的用例中,我需要控制" mySelector"由第三个选择器" controlSelector",方式:

  • 如果" controlSelector"是假的," mySelector"即使在" selectorA"的情况下也不评估新值。和/或" selectorB"更改,并返回记忆值

  • 如果" controlSelector"是的," mySelector"表现正常。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

选择器是纯函数..当输入参数改变时,它将重新计算。

对于您的情况,最好有另一个状态/对象来存储先前的迭代值。 您可以将其作为选择器传递,并根据controlSelector值确定您可以返回的内容。

state : {
  previousObj: {
    ...
  }
}

const prevSelector = createSelector(
  ...,
  (state) => state.previousObj
 )

const controlSelector = createSelector(...);

const mySelector = createSelector(
  controlSelector,
  prevSelector,
  selectorA,
  selectorB,
  (control, a, b) => {
    if(control) {
      return prevSelector.previousObj
    } else {
      return {
        field1: a.field1,
        field2: b.field2
      };
    }
  } 
)

答案 1 :(得分:0)

很抱歉延迟... 我终于解决了不使用NGRX选择器构建那些“较高选择器”并创建具有使用CombineLatest,filter,map和starWith

功能的类的问题。
getPendingTasks(): Observable<PendingTask[]> {
  return combineLatest(
    this.localStore$.select(fromUISelectors.getEnabled),
    this.localStore$.select(fromUISelectors.getShowSchoolHeadMasterView),
    this.memStore$.select(fromPendingTaskSelectors.getAll)).pipe(
      filter(([enabled, shmView, tasks]) => enabled),
      map(([enabled, shmView, tasks]) => {
        console.log('getPendingTasks');
        return tasks.filter(task => task.onlyForSchoolHeadMaster === shmView);
      }),
      startWith([])
    );
}

使用这种“选择器”使NGRX选择器保持简单并进行繁重的工作(尽管在本示例中什么也没有做):   -将生成初始默认值(startWith)   -过滤条件失败时将不会生成新值(即,如果未启用,则其他可观察对象的任何更改都不会触发该可观察对象的新值)