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 相关文章推荐
js 未结束的字符串常量错误解决方法
Jun 13 Javascript
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
Mar 30 Javascript
js实现一个省市区三级联动选择框代码分享
Mar 06 Javascript
JS实现简单的二元方程计算器功能示例
Jan 03 Javascript
JavaScript基础之AJAX简单的小demo
Jan 29 Javascript
React利用插件和不用插件实现双向绑定的方法详解
Jul 03 Javascript
浅谈Angular4实现热加载开发旅程
Sep 08 Javascript
javascript实现Emrips反质数枚举的示例代码
Dec 06 Javascript
浅谈Webpack 是如何加载模块的
May 24 Javascript
node上的redis调用优化示例详解
Oct 30 Javascript
npm全局环境变量配置详解
Dec 15 Javascript
原型和原型链 prototype和proto的区别详情
Nov 02 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求两个文件的相对路径
2013/06/20 PHP
php实现邮件发送并带有附件
2014/01/24 PHP
PHP等比例压缩图片的实例代码
2018/07/26 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
jquery 操作单选框,复选框,下拉列表实现代码
2009/10/27 Javascript
jQuery EasyUI API 中文文档 - Draggable 可拖拽
2011/09/29 Javascript
js日期对象兼容性的处理方法
2014/01/28 Javascript
常用的jquery模板插件——jQuery Boilerplate介绍
2014/09/23 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
2015/10/01 Javascript
常用javascript表单验证汇总
2020/07/20 Javascript
深入解析jQuery中Deferred的deferred.promise()方法
2016/05/03 Javascript
微信小程序 选择器(时间,日期,地区)实例详解
2016/11/16 Javascript
bootstrap快速制作后台界面
2016/12/05 Javascript
PHP实现本地图片上传和验证功能
2017/02/27 Javascript
BootStrap表单时间选择器详解
2017/05/09 Javascript
JS实现点餐自动选择框(案例分析)
2019/12/10 Javascript
Vue项目移动端滚动穿透问题的实现
2020/05/19 Javascript
python list使用示例 list中找连续的数字
2014/01/27 Python
Python中规范定义命名空间的一些建议
2016/06/04 Python
Python IDLE入门简介
2017/12/08 Python
基于PyQT实现区分左键双击和单击
2020/05/19 Python
Python函数必须先定义,后调用说明(函数调用函数例外)
2020/06/02 Python
python小白学习包管理器pip安装
2020/06/09 Python
卡拉威高尔夫官方网站:Callaway Golf
2020/09/16 全球购物
银行实习生自我鉴定范文
2013/09/19 职场文书
卫校护理专业毕业生求职信
2013/11/26 职场文书
车间班组长的职责
2013/12/13 职场文书
座谈会主持词
2014/03/20 职场文书
《锄禾》教学反思
2014/04/08 职场文书
水利局群众路线专题民主生活会发言材料
2014/09/21 职场文书
一年级小学生评语大全
2014/12/25 职场文书
新教师个人总结
2015/02/06 职场文书
暑期辅导班宣传单
2015/07/14 职场文书
Python制作一个随机抽奖小工具的实现
2021/07/07 Python
星际争霸 Light vs Action 一场把教主看到鬼畜的比赛
2022/04/01 星际争霸