使用 NgRx 时如何更新 mat table 行?

How to update a mat table row when NgRx is used?

我需要使用垫子显示一些数据 table。 其中一列将包含一个滑动开关,通过它我可以更改 属性(我们称之为 'active')。

我也在使用 NgRx store/modify 数据。

因此,状态是全局的并保存在 NgRx 存储中。 我的解决方案是使用选择器获取数据并定义更改 'active' 属性 的操作。该动作将由减速器处理。

数据更改后,选择器将 return 一个新值,table 将反映该值。

这是主要成分:

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

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

这里是完整的example

我的问题是该解决方案似乎效率不高。如果我使用开发人员工具检查 DOM 并更新一行,那么每一行似乎都被重绘,而不仅仅是更新的那一行。 此外,缺少滑动切换的动画(我猜是因为整个 table 正在重绘)。

我搜索了更好的替代方案,但我找不到,尽管这应该是一个流行的要求。

所以,我的问题是如何在使用 NgRx 时从 mat table 更新一行?

谢谢!

当行的数据发生更改时,这些行会重新呈现。因此我会责怪 toggleActiveStatus.

的 reducer

在完整的示例中,我们可以找到 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,
      }),
    };
  })
);

动画问题来自 table 更新。 我们单击切换按钮,它开始动画,table 获取新数据并使用新状态重新渲染切换按钮,从而终止动画。 因此我们需要延迟商店更新,最好的部分是在调度中进行。

修复可以这样

  updateActiveStatus(element: PeriodicElement) {
    setTimeout(() => this.store.dispatch(toggleActiveStatus({id: element.id})), 150);
  }