Antd的Table组件嵌套Table以及选择框联动操作


Posted in Javascript onOctober 24, 2020

一、需求

在使用Table组件嵌套Table时,父子Table的选择框需要联动,即父Table选中,该行下的子Table需要全选中,某一个子Table全部选中,则该子Table所在的父Table那一行也需要选中。

二、Table的rowSelection配置

父子Table联动,就不能使用OnChange,需要使用OnSelect以及OnSelectAll手动配置。

selectedRowKeys:指定选中项的key数组

OnSelect:手动选择/取消选择某行的回调

OnSelect(record, selected, selectedRows)

record:选中的当前行数据

selected:选中状态,true:选中,false:取消选中

 

selectedRows:选择的数组

OnSelectAll:手动选择/取消选择所有行的回调

OnSelect(selected, selectedRows, changeRows)

 

selected:选中状态,true:选中,false:取消选中

selectedRows:选择的数组

changeRows:改变的所有数组

三、根据antd文档搭建Table嵌套Table界面

import React, { useEffect, useState } from 'react';
import { Table, } from 'antd'
export default () => {
 const dataSource: any = [
 {
  key: '1',
  title: '餐饮酒店/服务员',
  number: '8家门店,共8人',
  time: '2020.05.25 15:35',
  childData: [
  {
   key: '1.1',
   jobTitle: '大桶大足浴-保安',
   num: '2人',
  },
  {
   key: '1.2',
   jobTitle: '大桶大足浴-保安',
   num: '5人',
  },
  ]
 },
 {
  key: '2',
  title: '餐饮酒店/收银员',
  number: '无门店,共5人',
  time: '2020.06.06 11:35',
  childData: [
  {
   key: '2.1',
   jobTitle: '大桶大足浴',
   num: '0人',
  },
  {
   key: '2.2',
   jobTitle: '大桶大足浴',
   num: '1人',
  },
  ]
 },
 ]
 const parentColumns: any = [
 {
  title: '工种',
  dataIndex: 'title',
  key: 'title',
 },
 {
  title: '关联门店数',
  dataIndex: 'number',
  key: 'number',
 },
 {
  title: '时间',
  dataIndex: 'time',
  key: 'time',
 },
 ]
 const expandedRowRender = (record: any, index: any, indent: any, expanded: any) => {
 const childData = record.childData
 const childColumns: any = [
  {
  title: '岗位名称',
  dataIndex: 'jobTitle',
  key: 'jobTitle'
  },
  {
  title: '招聘人数',
  dataIndex: 'num',
  key: 'num'
  },
 ]
 return <Table columns={childColumns} dataSource={childData} pagination={false} rowSelection={childRowSelection} />
 }
 return (
 <div>
  <Table columns={parentColumns} dataSource={dataSource} expandable={{ expandedRowRender }} rowSelection={parentRowSelection} />
 </div>
 );
}

四、开始配置rowSelection

1、配置父子Table的rowSelection

const childRowSelection = {
 selectedRowKeys: childSelectedRowKeys,
 onSelect: onChildSelectChange,
 onSelectAll: onChildSelectAll
 }
 const parentRowSelection = {
 selectedRowKeys: parentSelectedRowKeys,
 onSelect: onParentSelectChange,
 onSelectAll: onParentSelectAll,
 }

2、创建childSelectedRowKeys,parentSelectedRowKeys变量,用来存放父子Table选中的key值

const [parentSelectedRowKeys, setParentSelectedRowKeys] = useState<any>([])

const [childSelectedRowKeys, setChildSelectedRowKeys] = useState<any>([])

3、设置子Table手动选择/取消某行的回调 onChildSelectChange

选择单个时,当前行选中,若将该Table的所有选项全部选中,则子Table对应的父Table所在的那一行也选中

const onChildSelectChange = (record: any, selected: any, selectedRows: any) => {
 let childArr: any = [...childSelectedRowKeys];
 //第一步 判断selected true:选中,将key值添加到childArr,false:取消选中,将key值从childArr中移除
 if (selected) {
  childArr.push(record.key)
 } else {
  childArr.splice(childArr.findIndex((item: any) => item === record.key), 1)
 }
//必须去除undefined,否则selectedRows会将其他子Table中选中的key值放到数组中,但是值为undefined,如:[ undefined,1,uundefined]
 selectedRows = selectedRows.filter((a: any) => a !== undefined) 
 //第二步,判断selectedRows的长度是否为data中child的长度,相等,就将父table选中,不等就不选中
 for (let item of dataSource) {
  if (item.childData.find((d: any) => d.key === record.key)) {
  let parentArr: any = [...parentSelectedRowKeys];
  if (item.childData.length === selectedRows.length) {
   parentArr.push(item.key)
  } else {
   if (parentArr.length && parentArr.find((d: any) => d === item.key)) {
   parentArr.splice(parentArr.findIndex((item1: any) => item1 === item.key), 1)
   }
  }
  setParentSelectedRowKeys(parentArr)
  break;
  }
 }
 setChildSelectedRowKeys(childArr)
 }

4、设置子Table手动选择/取消选择所有行的回调onChildSelectAll

当选择全选时,子Table全部选中,并且该子table对应的父table行也选中,取消全选时,子Table全部取消选中,父Table行也取消选中

const onChildSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
 //第一步:判断selected,true:将子Table全部选中,false:将子Table全部取消选中
 let childArr: any = [...childSelectedRowKeys];
 if (selected) {
  //全选
  childArr = Array.from(new Set([...childArr, ...changeRows.map((item: any) => item.key)]))
 } else {
  //取消全选
  childArr = childArr.filter((item: any) => !changeRows.some((e: any) => e.key === item))
 }
  //第二步:找到子Table对应的父Table的所在行,再判断selected,true:将父Table所在行选中,false:将父Table所在行取消选中
 for (let item of dataSource) {
  if (item.childData.find((d: any) => d.key === changeRows[0].key)) {
  let parentArr: any = [...parentSelectedRowKeys];
  if (selected) {
   //全选
   parentArr.push(item.key)
  } else {
   //取消全选
   parentArr.splice(parentArr.findIndex((item: any) => item === item.key), 1)
  }
  setParentSelectedRowKeys(parentArr)
  break;
  }
 }
 setChildSelectedRowKeys(childArr)
 }

5、设置父Table手动选择/取消某行的回调 onParentSelctChange

当选择父Table某一行时,该行下的子Table全部选中,取消选择时,该行下的子Table也全部取消选中

const onParentSelectChange = (record: any, selected: any, selectedRows: any) => {
 let patentArr: any = [...parentSelectedRowKeys];
 let childArr: any = [...childSelectedRowKeys];
 //setChildArr:选择父Table下的所有子选项
 let setChildArr = dataSource.find((d: any) => d.key === record.key).childData.map((item: any) => item.key)
 //第一步 判断selected true:选中,false,取消选中
 if (selected) {
  //第二步,父Table选中,子Table全选中(全部整合到一起,然后去重)
  patentArr.push(record.key)
  childArr = Array.from(new Set([...setChildArr, ...childArr]))
 } else {
  //第二步,父Table取消选中,子Table全取消选中(针对childArr,过滤掉取消选中的父Table下的所有子Table的key)
  patentArr.splice(patentArr.findIndex((item: any) => item === record.key), 1)
  childArr = childArr.filter((item: any) => !setChildArr.some((e: any) => e === item))
 }
 //第三步,设置父,子的SelectedRowKeys
 setParentSelectedRowKeys(patentArr)
 setChildSelectedRowKeys(childArr)
 }

6、设置父Table手动选择/取消选择所有行的回调onParentSelectAll

全选时,父Table全部选中,所有对应的子Table也全部选中。取消全选时,父Table取消选中,所有子Table也取消选中

const onParentSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
 let patentArr: any = [...parentSelectedRowKeys];
 let setChildArr: any = [];
//将改变的父Table下的子Table下的key都添加到setChildArr中
 changeRows.forEach((e: any) => {
  setChildArr = [...setChildArr, ...e.childData.map((item: any) => item.key)]
 });
 //第一步判断selected true:全选,false:取消全选
 if (selected) {
  //第二步:父Table选中,子Table全选中,设置子Table的SelectedRowKeys
  patentArr = Array.from(new Set([...patentArr, ...changeRows.map((item: any) => item.key)]))
  setChildSelectedRowKeys(setChildArr)
 } else {
  //第二步:父Table取消选中,子Table全取消选中,设置子Table的SelectedRowKeys
  patentArr = patentArr.filter((item: any) => !changeRows.some((e: any) => e.key === item))
  setChildSelectedRowKeys([])
 }
 //第三步:设置父Table的SelectedRowKeys
 setParentSelectedRowKeys(patentArr)
 }

这样,父子Table的选择框联动就完成了,

注意:dataSource数据格式根据自己的格式而定

五、完整Demo

Table嵌套Table完整代码

import React, { useEffect, useState } from 'react';
import { Table, Button } from 'antd'
import { PlusOutlined } from '@ant-design/icons';
export default () => {
 const [parentSelectedRowKeys, setParentSelectedRowKeys] = useState<any>([])
 const [childSelectedRowKeys, setChildSelectedRowKeys] = useState<any>([])
 console.log(parentSelectedRowKeys, 'parentSelectedRowKeys')
 console.log(childSelectedRowKeys, 'childSelectedRowKeys')
 const dataSource: any = [
 {
  key: '1',
  title: '餐饮酒店/服务员',
  number: '8家门店,共8人',
  time: '2020.05.25 15:35',
  childData: [
  {
   key: '1.1',
   jobTitle: '大桶大足浴-保安',
   num: '2人',
  },
  {
   key: '1.2',
   jobTitle: '大桶大足浴-保安',
   num: '5人',
  },
  ]
 },
 {
  key: '2',
  title: '餐饮酒店/收银员',
  number: '无门店,共5人',
  time: '2020.06.06 11:35',
  childData: [
  {
   key: '2.1',
   jobTitle: '大桶大足浴',
   num: '0人',
  },
  {
   key: '2.2',
   jobTitle: '大桶大足浴',
   num: '1人',
  },
  ]
 },
 ]
 const parentColumns: any = [
 {
  title: '工种',
  dataIndex: 'title',
  key: 'title',
 },
 {
  title: '关联门店数',
  dataIndex: 'number',
  key: 'number',
 },
 {
  title: '时间',
  dataIndex: 'time',
  key: 'time',
 },
 ]
 const expandedRowRender = (record: any, index: any, indent: any, expanded: any) => {
 const childData = record.childData
 const childColumns: any = [
  {
  title: '岗位名称',
  dataIndex: 'jobTitle',
  key: 'jobTitle'
  },
  {
  title: '招聘人数',
  dataIndex: 'num',
  key: 'num'
  },
 ]
 return <Table columns={childColumns} dataSource={childData} pagination={false} rowSelection={childRowSelection} />
 }
 const onParentSelectChange = (record: any, selected: any, selectedRows: any) => {
 let patentArr: any = [...parentSelectedRowKeys];
 let childArr: any = [...childSelectedRowKeys];
 //setChildArr:选择父Table下的所有子选项
 let setChildArr = dataSource.find((d: any) => d.key === record.key).childData.map((item: any) => item.key)
 //第一步 判断selected true:选中,false,取消选中
 if (selected) {
  //第二步,父Table选中,子Table全选中
  patentArr.push(record.key)
  childArr = Array.from(new Set([...setChildArr, ...childArr]))
 } else {
  //第二步,父Table取消选中,子Table全取消选中
  patentArr.splice(patentArr.findIndex((item: any) => item === record.key), 1)
  childArr = childArr.filter((item: any) => !setChildArr.some((e: any) => e === item))
 }
 //第三步,设置父,子的SelectedRowKeys
 setParentSelectedRowKeys(patentArr)
 setChildSelectedRowKeys(childArr)
 }
 const onParentSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
 let patentArr: any = [...parentSelectedRowKeys];
 let setChildArr: any = [];
 changeRows.forEach((e: any) => {
  setChildArr = [...setChildArr, ...e.childData.map((item: any) => item.key)]
 });
 //第一步判断selected true:全选,false:取消全选
 if (selected) {
  //第二步:父Table选中,子Table全选中,设置子Table的SelectedRowKeys
  patentArr = Array.from(new Set([...patentArr, ...changeRows.map((item: any) => item.key)]))
  setChildSelectedRowKeys(setChildArr)
 } else {
  //第二步:父Table取消选中,子Table全取消选中,设置子Table的SelectedRowKeys
  patentArr = patentArr.filter((item: any) => !changeRows.some((e: any) => e.key === item))
  setChildSelectedRowKeys([])
 }
 //第三步:设置父Table的SelectedRowKeys
 setParentSelectedRowKeys(patentArr)
 }
 const onChildSelectChange = (record: any, selected: any, selectedRows: any) => {
 //record:当前操作行
 //selected选中状态
 //selectedRows:选择的数组
 let childArr: any = [...childSelectedRowKeys];
 //第一步 判断selected true:选中,false:取消选中
 if (selected) {
  childArr.push(record.key)
 } else {
  childArr.splice(childArr.findIndex((item: any) => item === record.key), 1)
 }
 selectedRows = selectedRows.filter((a: any) => a !== undefined)
 //第二步,判断selectedRows的长度是否为data中child的长度,相等,就将父table选中,不等就不选中
 for (let item of dataSource) {
  if (item.childData.find((d: any) => d.key === record.key)) {
  let parentArr: any = [...parentSelectedRowKeys];
  if (item.childData.length === selectedRows.length) {
   parentArr.push(item.key)
  } else {
   if (parentArr.length && parentArr.find((d: any) => d === item.key)) {
   parentArr.splice(parentArr.findIndex((item1: any) => item1 === item.key), 1)
   }
  }
  setParentSelectedRowKeys(parentArr)
  break;
  }
 }
 setChildSelectedRowKeys(childArr)
 }
 const onChildSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
 //selected:全选true 取消全选false
 //selectedRows:改变后的
 //changeRows:改变的所有数组
 //第一步:判断selected,true:将子Table全部选中,false:将子Table全部取消选中
 let childArr: any = [...childSelectedRowKeys];
 if (selected) {
  //全选
  childArr = Array.from(new Set([...childArr, ...changeRows.map((item: any) => item.key)]))
 } else {
  //取消全选
  childArr = childArr.filter((item: any) => !changeRows.some((e: any) => e.key === item))
 }
 //第二步:找到子Table对应的父Table的所在行,再判断selected,true:将父Table所在行选中,false:将父Table所在行取消选中
 for (let item of dataSource) {
  if (item.childData.find((d: any) => d.key === changeRows[0].key)) {
  let parentArr: any = [...parentSelectedRowKeys];
  if (selected) {
   //全选
   parentArr.push(item.key)
  } else {
   //取消全选
   parentArr.splice(parentArr.findIndex((item: any) => item === item.key), 1)
  }
  setParentSelectedRowKeys(parentArr)
  break;
  }
 }
 setChildSelectedRowKeys(childArr)
 }
 const childRowSelection = {
 selectedRowKeys: childSelectedRowKeys,
 onSelect: onChildSelectChange,
 onSelectAll: onChildSelectAll
 }
 const parentRowSelection = {
 selectedRowKeys: parentSelectedRowKeys,
 onSelect: onParentSelectChange,
 onSelectAll: onParentSelectAll,
 }

 return (
 <div>
  <Table columns={parentColumns} dataSource={dataSource} expandable={{ expandedRowRender }} rowSelection={parentRowSelection} />
 </div>
 );
}

以上这篇Antd的Table组件嵌套Table以及选择框联动操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
document.all与WEB标准
May 13 Javascript
JS中不为人知的五种声明Number的方式简要概述
Feb 22 Javascript
javascript 动态创建表格
Jan 08 Javascript
javascript操作select元素实例分析
Mar 27 Javascript
Vue常用指令V-model用法
Mar 08 Javascript
在JS中如何把毫秒转换成规定的日期时间格式实例
May 11 Javascript
js实现股票实时刷新数据案例
May 14 Javascript
layui select动态添加option的实例
Mar 07 Javascript
vue2使用keep-alive缓存多层列表页的方法
Sep 21 Javascript
教你搭建按需加载的Vue组件库(小结)
Jul 29 Javascript
15 分钟掌握vue-next响应式原理
Oct 13 Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 Javascript
解决Antd 里面的select 选择框联动触发的问题
Oct 24 #Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
Oct 24 #Javascript
jquery插件懒加载的示例
Oct 24 #jQuery
在react-antd中弹出层form内容传递给父组件的操作
Oct 24 #Javascript
Antd下拉选择,自动匹配功能的实现
Oct 24 #Javascript
在react项目中使用antd的form组件,动态设置input框的值
Oct 24 #Javascript
Vue-Ant Design Vue-普通及自定义校验实例
Oct 24 #Javascript
You might like
php sprintf()函数让你的sql操作更安全
2008/07/23 PHP
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
解析WordPress中控制用户登陆和判断用户登陆的PHP函数
2016/03/01 PHP
YII Framework框架教程之安全方案详解
2016/03/14 PHP
PHP实现获取第一个中文首字母并进行排序的方法
2017/05/09 PHP
thinkPHP中U方法加密传递参数功能示例
2018/05/29 PHP
PHP判断函数是否被定义的方法
2019/06/21 PHP
PHP abstract与interface之间的区别
2013/11/11 Javascript
在JS数组特定索引处指定位置插入元素
2014/07/27 Javascript
node.js中的fs.appendFile方法使用说明
2014/12/17 Javascript
jquery Easyui快速开发总结
2015/08/20 Javascript
微信小程序 绘图之饼图实现
2016/10/24 Javascript
zTree实现节点修改的实时刷新功能
2017/03/20 Javascript
node.js中fs.stat与fs.fstat的区别详解
2017/06/01 Javascript
jQuery中的$是什么意思及 $. 和 $().的区别
2018/04/20 jQuery
JavaScript 双向链表操作实例分析【创建、增加、查找、删除等】
2020/04/28 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
[01:21]辉夜杯战队访谈宣传片—CDEC
2015/12/25 DOTA
[01:04]DOTA2上海特锦赛现场采访 FreeAgain遭众解说围攻
2016/03/25 DOTA
python实现定制交互式命令行的方法
2014/07/03 Python
python黑魔法之编码转换
2016/01/25 Python
python函数的5种参数详解
2017/02/24 Python
Python实现单词翻译功能
2017/06/06 Python
HTML中使用python屏蔽一些基本功能的方法
2017/07/07 Python
使用Python将Mysql的查询数据导出到文件的方法
2019/02/25 Python
python多任务之协程的使用详解
2019/08/26 Python
Python实现随机取一个矩阵数组的某几行
2019/11/26 Python
python 非线性规划方式(scipy.optimize.minimize)
2020/02/11 Python
控制工程专业个人求职信
2013/09/25 职场文书
自主招生自荐信
2013/12/08 职场文书
给水工程专业毕业生自荐信
2014/01/28 职场文书
书法兴趣小组活动总结
2014/07/07 职场文书
2014年教研组工作总结
2014/11/26 职场文书
企业法人任命书
2015/09/21 职场文书
GoLang中生成UUID唯一标识的实现
2021/05/08 Golang