Параметр ngrx для выбора функции

Есть ли способ передать параметры функциям выбора ngrx?

Ниже приведен мой вариант использования:

Я веду список комментариев в магазине.

Я написал один компонент для представления одного комментария. Итак, один компонент CommentComponent знает идентификатор объекта компонента

Каждый комментарий будет иметь такие свойства, как НравитсяBy, reportBy, ... и т. Д. В пользовательском интерфейсе я показываю все компоненты, используя * ngFor.

Теперь я хочу, чтобы мой компонент комментариев подписывался только на один объект комментария, используя идентификатор компонента.

Прямо сейчас я подписываюсь на все комментарии в компоненте верхнего уровня и передаю каждый комментарий в CommentCompoent в качестве входных данных.

Текущий подход не является чистым, потому что стратегия обнаружения угловых изменений (даже если я использую onPush) должна отображать DOM для всех комментариев, даже если изменяется только один комментарий.

Оцените любые предложения, по которым я могу передать идентификатор комментария в функцию выбора, чтобы каждый компонент CommentComponent мог подписаться только на один комментарий.

Заранее спасибо, Судхакар


person user2960993    schedule 08.09.2017    source источник
comment
Вы подписываетесь на свой комментарий внутри компонента комментариев? Если да, вам лучше подписаться на массив в родительском компоненте и передать каждый из них с помощью @input. Вы должны сделать свой комментарий как можно более тупым;)   -  person maxime1992    schedule 08.09.2017
comment
@Maxime в настоящее время я делаю то же, что вы упомянули, но angular занимает слишком много времени для рендеринга всякий раз, когда изменяется какой-либо комментарий   -  person user2960993    schedule 08.09.2017
comment
Это странно. Репо с открытым исходным кодом? Можете ли вы воспроизвести на Plunkr или Stackblitz?   -  person maxime1992    schedule 08.09.2017
comment
Я знаю, что это старый, но вы используете трек? Это должно предотвратить повторную рендеринг компонентов комментариев на экране. Вы также нашли ответ на этот вопрос? У меня есть другой вариант использования, для которого я хочу это сделать.   -  person jgerstle    schedule 09.04.2018
comment
По чему трек?   -  person user2960993    schedule 11.04.2018
comment
Еще один голос за использование trackBy, это гарантирует отсутствие (дорогостоящих) операций записи в DOM, даже если ваши данные мутируют. angular.io/api/common/NgForOf#ngForTrackBy   -  person bc1105    schedule 08.05.2018


Ответы (3)


Начиная с NgRx 6.1, вы можете использовать селектор с реквизитами.

export const getCount = () =>   
  createSelector(     
    (state, props) => state.counter[props.id],     
    (counter, props) => counter * props.multiply
);

Для получения дополнительной информации и различных способов ознакомьтесь с моей статьей NgRx: параметризованные селекторы

person timdeschryver    schedule 06.01.2019

Да, вы можете передать параметры в селектор ngrx, и вы можете сделать это таким образом

со стороны компонентов

this.store.select(getComments(user_id));

со стороны селектора

export const getComments = (user_id) => createSelector(
  getData,
  (store) => store.comments 
);
person Jaya Krishna    schedule 16.05.2018
comment
Предотвращает ли это мемоизацию (которая, я думаю, является основной целью createSelector), возвращая каждый раз новый селектор? И это рекомендуется в официальной документации? - person Marcus; 20.06.2018
comment
@Marcus, каждый раз, когда вы используете getComments, он будет создавать новый экземпляр селектора. Таким образом, мемоизация по-прежнему будет применяться здесь. Дополнительную информацию можно найти в статье NgRx: параметризованные селекторы. - person timdeschryver; 06.01.2019
comment
Кажется, не работает, когда вы хотите переопределить такой селектор: ngrx.io / guide / store / testing # using-mock-selectors - person CularBytes; 07.10.2020

@ CularBytes Я уже некоторое время работал над аналогичной проблемой, используя этот подход с тестированием, и думаю, что нашел способ заставить его работать.

С селектором

export const getItemsByProperty = (property: string, value: any) => createSelector(getAllItems, (items: ItemObj[]) => items.filter((item) => item[property] == value));

и где

export const getAllItems = createSelector(getState, (state) => selectAll(state.items));

в моем файле модульного теста компонентов я переопределяю селектор для базового вызова селектора getItemsByProperty, getAllItems, данными, а затем ожидаю отфильтрованные данные в моих тестах. Если вы хотите вернуть изменения, просто обновите результат getAllItems.

person A Hutch    schedule 18.12.2020