当前位置: 移动技术网 > IT编程>脚本编程>Python > Antd的Table组件嵌套Table以及选择框联动操作

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

2020年10月24日  | 移动技术网IT编程  | 我要评论
一、需求在使用table组件嵌套table时,父子table的选择框需要联动,即父table选中,该行下的子table需要全选中,某一个子table全部选中,则该子table所在的父table那一行也

一、需求

在使用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以及选择框联动操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网