Как обновить строку таблицы матов при использовании NgRx? - PullRequest
1 голос
/ 29 апреля 2020

У меня есть требование для отображения некоторых данных с использованием таблицы матов. В одном из столбцов будет слайд-переключатель, с помощью которого я могу изменить свойство (назовем его «активным»).

Я также использую NgRx для хранения / изменения данных.

Итак, состояние является глобальным и сохраняется в хранилище NgRx. Мое решение состоит в том, чтобы получить данные с помощью селектора и определить действие для изменения свойства 'active'. Действие будет обработано редуктором.

После изменения данных селектор вернет новое значение, и таблица отобразит это.

Это основной компонент:

ngOnInit() {
   this.dataSource = this.store.pipe(select(selectPeriodicElements));
}

updateActiveStatus(element: PeriodicElement) {
   this.store.dispatch(toggleActiveStatus({id: element.id}));
}

Вот полный пример

Моя проблема в том, что решение кажется неэффективным. Если я использую инструменты разработчика для проверки DOM и обновляю одну строку, то кажется, что каждая строка перерисовывается, а не только та, которая была обновлена. Кроме того, отсутствует анимация для переключения слайдов (я думаю, что перерисовывается вся таблица).

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

Итак, мой вопрос: как обновить строку из таблицы матов при использовании NgRx?

Спасибо!

1 Ответ

1 голос
/ 05 мая 2020

Строки перерисовываются, когда их данные были изменены. Поэтому я бы назвал редуктор toggleActiveStatus.

. В полном примере мы можем найти JSON.parse(JSON.stringify(state.elements)), это худший вариант для хранилища ngrx :), потому что это означает, что все в состоянии было изменено и в результате - все перерисовывается.

Вместо JSON всегда обновляйте узел, который вы хотите изменить, и ничего больше. Это правило поможет вам доставлять хорошо работающие приложения.

Код ниже реализует это поведение.

const periodicElementsReducer = createReducer(
  initialState,
  on(toggleActiveStatus, (state, {id}) => {
    return {
      ...state,
      elements: state.elements.map(element => element.id !== id ? element : {
        ...element,
        activate: !element.activate,
      }),
    };
  })
);

Проблема с анимацией возникает из-за обновления таблицы. Мы нажимаем на переключатель, он запускает анимацию, таблица получает новые данные и повторно отображает переключатель с новым состоянием, которое убивает анимацию. Поэтому нам нужно отложить обновление магазина, лучше всего сделать это, например, в рассылке.

Исправление может быть таким

  updateActiveStatus(element: PeriodicElement) {
    setTimeout(() => this.store.dispatch(toggleActiveStatus({id: element.id})), 150);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...