Как можно управлять оценкой селектора 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
};
}
}
)