使用 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);
}
我需要使用垫子显示一些数据 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
.
在完整的示例中,我们可以找到 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);
}