Как можно управлять оценкой селектора ngrx-store?

У меня есть селектор:

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

Я знаю, что селектор оценивается при изменении любого из его входов.

В моем случае мне нужно управлять "mySelector" с помощью третьего селектора "controlSelector", таким образом:

  • если "controlSelector" равно false, "mySelector" не оценивает новое значение даже в случае изменения "selectorA" и / или "selectorB" и возвращает запомненное значение

  • если "controlSelector" имеет значение true, "mySelector" ведет себя нормально.

Какие-либо предложения?

2 ответа

Извините за задержку... Я наконец-то решил проблему, не используя селекторы NGRX для создания этих "высших селекторов" и создав класс с функциями, которые используют combLatest, 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) - не будет генерировать новое значение, пока условие фильтра не выполняется (что если не включено, любые изменения в других наблюдаемых не запускают новое значение этой наблюдаемой)

Селекторы - это чистые функции. Они будут пересчитываться при изменении входных аргументов.

В вашем случае лучше иметь другое состояние / объект для хранения предыдущих значений итерации. Вы можете передать это как селектор и на основе значения 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
      };
    }
  } 
)
Другие вопросы по тегам