问题:
antd Table提供了数据行可选择的操作,但是如果分页数据是从后端获取,切换页码后之前的分页数据就没有了,回到之前的页面选中状态也无法保留。
解决:
这里对ant Table表格组件进行了封装,实现了在分页数据动态获取时切换页码其他页选中的数据和状态仍保留的功能
思路:
1.定义curPageSelectedRowKeys存储当前页选中数据的key值数组,selectedRows存储所有选中数据
2.监听当前页数据选中/取消选中和全选/取消全选操作,更新curPageSelectedRowKeys和selectedRows
3.当页码切换时根据selectedRows来确定当前页面哪些数据是选中状态从而确定curPageSelectedRowKeys
组件代码:
/*
* @Author: liu
* @Date: 2021-08-24 14:35:53
* @LastEditTime: 2021-09-08 22:11:01
* @LastEditors: Please set LastEditors
* @Description: 表格自定义选中项,前端分页,分页后保留之前选中数据
* @FilePath: \chq-datamarket-frontend\src\apps\views\shared\customSelectTable\customSelectTable.tsx
*/
import React, { useEffect, useState } from "react";
import { Pagination, Table } from "antd";
interface CustomSelectTableProps {
columns: any[]; //表格列
dataSource: any[]; //表格数据(当前页)
curPageSelectedRowKeys: number[]; //当前页选中数据key值数组
curPageSelectedRowKeysChange: (key: any[]) => void; //curPageSelectedRowKeys改变
selectedRows: any[]; //所有选中数据
selectedRowsChange: (row: any[]) => void;
pageOption: {
//分页参数
page: number;
pageChange: (page) => void;
pageSize: number;
sizeChange: (size: number) => void;
totalCount: number;
showSizeChanger?: boolean;
pageSizeOptions?: any[];
};
tableClass?: string;
}
export default function customSelectTable(props: CustomSelectTableProps) {
useEffect(() => {
updateSelectData();
}, [props.dataSource]);
const rowSelection = {
selectedRowKeys: props.curPageSelectedRowKeys,
onSelect: (record, selected, selectedRows, nativeEvent) => {
onSelectChange(record, selected, selectedRows);
},
onSelectAll: onSelectAll,
hideDefaultSelections: true
};
/**
* 更新选中数据,当表格数据变化后,重新计算当前页选中数据
*/
function updateSelectData() {
const curPageSelectIndex = [];
const { selectedRows } = props;
if (selectedRows && selectedRows.length) {
props.dataSource.map(d => {
selectedRows.find(sd => {
//key是数据的唯一标识,需要在dataSource中确定每条数据的key值
if (d.key === sd.key) {
curPageSelectIndex.push(d.key);
return true;
}
});
});
}
props.curPageSelectedRowKeysChange(curPageSelectIndex);
}
/**
* 数据选中/取消选中
* @param record 当前操作数据
* @param selected 是否选中
* @param selectedRows 当前页所有选中数据
*/
function onSelectChange(record, selected, selectedRows) {
props.curPageSelectedRowKeysChange(selectedRows.map(it => it.key));
if (selected) {
props.selectedRowsChange([...props.selectedRows, record]);
} else {
const selectedrows = props.selectedRows.filter(it => {
return it.key !== record.key;
});
props.selectedRowsChange(selectedrows);
}
}
//全选操作
function onSelectAll(selected: any, selectedRows: any, changeRows: any) {
props.curPageSelectedRowKeysChange(selectedRows.map(it => it.key));
const changeRowsId: string[] = changeRows.map(it => {
return it.key;
});
if (selected) {
props.selectedRowsChange([...props.selectedRows, ...changeRows]);
} else {
const selectrows = props.selectedRows.filter(it => {
return !changeRowsId.includes(it.key);
});
props.selectedRowsChange(selectrows);
}
}
function pageChange(page) {
props.pageOption.pageChange(page);
}
function pageSizeChange(cur, size) {
props.pageOption.sizeChange(size);
}
return (
<>
<Table
columns={props.columns}
dataSource={props.dataSource}
className={`tableBase ${props.tableClass}`}
rowSelection={rowSelection}
pagination={false}
/>
<div className="commonPage">
<div className="pageDesc">{`每页${props.pageOption.pageSize}条记录,共${props.pageOption.totalCount}条`}</div>
<Pagination
className="dataPage"
current={props.pageOption.page}
pageSize={props.pageOption.pageSize}
showSizeChanger={props.pageOption.showSizeChanger}
pageSizeOptions={
props.pageOption.pageSizeOptions || ["15", "50", "100"]
}
onShowSizeChange={pageSizeChange}
total={props.pageOption.totalCount}
showQuickJumper={true}
onChange={pageChange}
/>
</div>
</>
);
}
使用示例:
import React, { Component } from "react";
import { Button, Input, Select, Pagination, message, Table } from "antd";
import CustomSelectTable from "../../../shared/customSelectTable/customSelectTable";
import { AppContext } from "../../../../utils/qe.util";
import "public/css/authorityApplication.css";
interface AuthorityApplicationProps {}
interface AuthorityApplicationStates {
tableData: any[];
curPageSelectedRowKeys: any[]; //当前页选中索引
selectedRows: any[]; //所有选中数据(除当前页)
page: number;
pageSize: number;
totalCount: number;
}
export default class AuthorityApplication extends Component<
AuthorityApplicationProps,
AuthorityApplicationStates
> {
static contextType = AppContext;
constructor(props) {
super(props);
this.state = {
tableData: [],
curPageSelectedRowKeys: [],
selectedRows: [],
page: 1,
pageSize: 12,
totalCount: 0
};
}
componentDidMount() {
this.getDataList();
}
private pageChange = page => {
this.setState(
{
page
},
() => {
this.getDataList();
}
);
};
private pageSizeChange = size => {
this.setState(
{
pageSize: size,
page: 1
},
() => {
this.getDataList();
}
);
};
//获取表格数据
private getDataList = () => {};
private submit = () => {
const { selectedRows } = this.state;
new Promise(res => {
//提交selectedRows
}).then(() => {
this.setState({
curPageSelectedRowKeys: [],
selectedRows: []
});
});
};
render() {
const {
tableData,
curPageSelectedRowKeys,
selectedRows,
page,
pageSize,
totalCount
} = this.state;
const columns: any = [
{
title: "序号",
align: "center",
dataIndex: "key",
render: (key: any, record: any, index: number) => Number(index) + 1
},
{
title: "名称",
dataIndex: "dataItemName",
key: "dataItemName",
align: "center"
}
];
return (
<div className="authorityApplicationContainer">
<CustomSelectTable
columns={columns}
dataSource={tableData}
tableClass="commonTable scrollBase"
curPageSelectedRowKeys={curPageSelectedRowKeys}
curPageSelectedRowKeysChange={keys => {
this.setState({
curPageSelectedRowKeys: keys
});
}}
selectedRows={selectedRows}
selectedRowsChange={row => {
this.setState({
selectedRows: row
});
}}
pageOption={{
page,
pageSize,
pageChange: this.pageChange,
sizeChange: this.pageSizeChange,
totalCount,
showSizeChanger: true,
pageSizeOptions: ["12", "50", "100"]
}}
/>
<div>
<Button onClick={this.submit}>提交</Button>
</div>
</div>
);
}
}
注意:
为了避免切换分页后前一页选中的状态在新数据页仍然保留的问题,在得到表格数据后为每条数据都加了key字段,其值可以为数据唯一标识对应的值如id,如果本身就有唯一的key字段则无需再添加。
this.setState({
tableData: (res.result.content || []).map(it => {
return { ...it, key: it.key || it.id };
}),
});
补充:
1.数据刷新后选中状态仍保留问题
如果选中了部分数据后,表格数据已经重新请求了,且curPageSelectedRowKeys和selectRoews都已经置空了,但是之前的选中状态仍然保留,查看Table的rowSelection属性是不是正确的设置了selectedRowKeys值(这里应该为curPageSelectedRowKeys),或者忘记添加selectedRowKeys
const rowSelection = {
selectedRowKeys: props.curPageSelectedRowKeys,//就是这个字段,笔者就是当时把selectedRowKeys写错了,导致了上述问题
onSelect: (record, selected, selectedRows, nativeEvent) => {
onSelectChange(record, selected, selectedRows);
},
onSelectAll: onSelectAll,
hideDefaultSelections: true
};