问题描述
用户在翻页后丢失已选中的数据,只能在已分页的数据中进行修改操作,尤其是在填写分步表单时,上一步及下一步也会丢失数据
主要API
- Ant Design :
onSelect: 用户手动选择/取消选择某行的回调
onSelectAll: 用户手动选择/取消选择所有行的回调
不使用 onSelectChange,原因为:当指定selectedRowKeys(需要被选中的id集合),会在表格渲染时重复setState,致使selectedRowKeys值丢失,无法保留选中状态
具体可参考: https://ant.design/components/table-cn/#rowSelection - Lodash :
_.remove: 移除数组中predicate(断言)返回为真值的所有元素
_.map: 遍历 collection(集合)中的每个元素后返回的结果,此处主要用来获取指定键的值数组
_.concat:合并两个数组或集合
_.uniqBy: 根据指定键比较进行去重
_.includes:判断数组是否包含某个元素
具体可参考: https://www.lodashjs.com/docs/latest
解决思路
起初想通过state去控制selectedRowKeys(选中项),但是由于分布填写表单的原因,在切换时会丢失state,因此采用Props控制选中项使其成为完全受控组件。
然后通过onSelect和onSelectAll控制用户手动触发选中项更改props值,而非onSelectChange只监控选中与否,避免选中项丢失的问题。
具体解决方法
- 数据层(models)
// 定义数据格式
export interface StateType {
selectedRowKeys?: any[];
selectedRows?: any[];
}
// 定义models格式
export interface ModelType {
namespace: string;
state: StateType;
effects: {};
reducers: {
saveSelectedRowKeys: Reducer<StateType>;
};
}
const Model: ModelType = {
namespace: 'formAndstepForm',
state: {
selectedRowKeys: [],
selectedRows: [],
},
effects: {},
reducers: {
saveSelectedRowKeys(state, { payload }) {
return {
...state,
...payload,
};
},
},
};
export default Model;
- 页面层(pages)
import React from 'react';
import ProTable, { ProColumns } from '@ant-design/pro-table';
import _ from 'lodash';
interface Step2Props extends Partial<ConnectProps> {
selectedRowKeys: any;
selectedRows: any;
}
interface Step2States {}
class Step2 extends React.Component<Step2Props, Step2States> {
/**
* @name: 手动选中复选框
* @msg:
* @param {type}
* @return:
*/
onSelect = (record: any, selected: any) => {
const mySelectedRows = this.props.selectedRows;
const { dispatch } = this.props;
if(selected){
mySelectedRows.push(record);
}else{
_.remove(mySelectedRows, (o: any) => {return o.deviceId === record.deviceId});
}
const selectedRowKeys = _.map(mySelectedRows,'id');
if(dispatch){
dispatch({
type: 'formAndstepForm/saveSelectedRowKeys',
payload: {
selectedRowKeys,
selectedRows: mySelectedRows,
},
});
}
}
onSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
let mySelectedRows = this.props.selectedRows;
const changeRowKeys = _.map(changeRows,'id');
const { dispatch } = this.props;
if(selected){
// 先连接再进行一次去重
mySelectedRows = _.uniqBy(_.concat(mySelectedRows,changeRows), 'id');
}else{
// 先判断包含再移除
_.remove(mySelectedRows, (o: any) => {return _.includes(changeRowKeys,o.deviceId)});
}
const selectedRowKeys = _.map(mySelectedRows,'id');
if(dispatch){
dispatch({
type: 'formAndstepForm/saveSelectedRowKeys',
payload: {
selectedRowKeys,
selectedRows: mySelectedRows,
},
});
}
}
render() {
const {
opcFilterTab,
loading,
paginationFilter,
selectedRowKeys,
} = this.props;
const columns: ProColumns<OpcFilterInfo>[] = [
];
const rowSelection = {
selectedRowKeys,
onSelect: this.onSelect,
onSelectAll: this.onSelectAll,
};
return (
<>
<ProTable
rowKey={(record) => record.id}
loading={loading}
columns={columns}
dataSource={opcFilterTab}
search={false}
toolBarRender={false}
rowSelection={rowSelection}
options={false}
tableAlertRender={false}
pagination={{
...paginationFilter,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () =>
`${paginationFilter ? paginationFilter.current : 0}/${
paginationFilter ? paginationFilter.totalPages : 0
}`,
}}
/>
</>
);
}
}
export default connect(
({
formAndstepForm,
}: {
formAndstepForm: StateType;
}) => ({
selectedRowKeys: formAndstepForm.selectedRowKeys,
selectedRows: formAndstepForm.selectedRows,
opcFilterTab: opc.opcFilterTab,
paginationFilter: opc.paginationFilter,
}),
)(Step2);
注意事项
针对数据处理可使用lodash使得代码整洁,可参考api理解使用,同时注意数据排序,避免选中项位置改变