日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

React使用antd Table生成层级多选组件

發(fā)布時(shí)間:2025/3/8 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 React使用antd Table生成层级多选组件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、需求

  用戶對(duì)不同的應(yīng)用需要有不同的權(quán)限,用戶一般和角色關(guān)聯(lián)在一起,新建角色的時(shí)候會(huì)選擇該角色對(duì)應(yīng)的應(yīng)用,然后對(duì)應(yīng)用分配權(quán)限。于是寫了一種實(shí)現(xiàn)的方式。首先應(yīng)用是一個(gè)二級(jí)樹,一級(jí)表示的是應(yīng)用分組,二級(jí)表示的是應(yīng)用,這是table的最左邊的數(shù)據(jù)。然后是按鈕的數(shù)據(jù),這里顯示在table的頭部。

二、效果圖如下

  

?三、具體代碼

  1.RoleApplicationTable.js

import React from 'react'; import RoleCheckbox from 'components/role/RoleCheckbox'; import {Menu, Table, message} from 'antd'; import Btn from 'components/public/BaseBtn'; import {connect} from 'react-redux'; import 'styles/less/personType.less'; import 'styles/less/basebtn.less'; import Map from 'components/role/Map'; import { operationRoleAppBtn, queryRoleAppBtnData} from 'actions/role';var mapStateToProps = function(state){return {roleData: state.getRole } }; //規(guī)范屬性類型 var propTypes = {personTypes: React.PropTypes.object,dispatch : React.PropTypes.func }; class RoleApplicationTable extends React.Component {constructor(props) {super(props);this.state = {};this.chooseApp = this.chooseApp.bind(this);this.addColName = this.addColName.bind(this);this.addDataPid = this.addDataPid.bind(this);this.onChecked = this.onChecked.bind(this);this.addChildrenRow = this.addChildrenRow.bind(this);this.addData = this.addData.bind(this);this.isGroupRow = this.isGroupRow.bind(this);this.checkGroupAndColumnState = this.checkGroupAndColumnState.bind(this);//確保 組全選 和 列 全選this.cid = 0;this.rowNum = 0;this.colNum = 0;//mapthis.checkboxIdMapState= new Map();//checkboxId 映射 Statethis.parentRow = new Map();//每個(gè)checkboxId節(jié)點(diǎn) 對(duì)應(yīng)最左邊的哪個(gè)應(yīng)用this.parentCol = new Map();//每個(gè)checkboxId節(jié)點(diǎn) 對(duì)應(yīng)最上邊的哪個(gè)按鈕this.childrenRow = new Map();//當(dāng)前行的所有子行this.checkboxIdMapData = new Map();//每個(gè)checkbox對(duì)應(yīng)的 appid,btnGroupId//保存數(shù)據(jù)this.checked = null;//標(biāo)識(shí)數(shù)據(jù)是 新增 還是 刪除this.dataQueue = [];// appid,btngroupId隊(duì)列//測(cè)試數(shù)據(jù)this.appData = [{name: '報(bào)表',id: "456",key: '5', children: [{ name: '合同價(jià)款', id: "45xx61", key: '6', },{ name: '合同臺(tái)賬', id: "45xf61", key: '7', }], }, { name: '圖標(biāo)', id: "789", key: '1', children: [{ name: '小圖標(biāo)', id: "45xx60", key: '4' },{ name: '大圖標(biāo)', id: "4xx560", key: '8' }] }];this.btnGroupColumns = [{id: '12xx3', name: '小部件', colname: 'name'}, {id:'43xx5', name:'顯示'}, {id:'43xfffx5', name:'test'}];}componentDidMount() {//const roleId = '4028968156b025da0156b027d0180000';const roleId = this.props.roleId;if(roleId) {//通過角色id加載 數(shù)據(jù)const { dispatch } = this.props;const querydata = {roleId: roleId};dispatch(queryRoleAppBtnData(querydata));}}componentWillReceiveProps(nextProps) {const {roleData} = nextProps;if (roleData.msg) {if(roleData.msg.indexOf('成功') >= 0)message.success(roleData.msg, 5);else if(roleData.msg.indexOf('失敗') >= 0)message.error(roleData.msg, 5);else message.info(roleData.msg, 5);// if (roleData.msg == '保存成功') {//角色保存成功后 仍然留在當(dāng)前頁面, 繼續(xù) 角色按鈕組權(quán)限// this.props.history.pushState(null, 'rolecenter');// } }}chooseApp(){this.props.chooseApp();}sendCheckData(){const { dispatch } = this.props;const queryData = {vos: this.dataQueue,//對(duì)應(yīng)后端的字段 };dispatch(operationRoleAppBtn(this.checked, queryData));}//// addChildrenRow(appData){//添加所有子行 標(biāo)識(shí)if(!appData) return;for(var i=0; i<appData.length; ++i) {//獲取行頭的checkboxIdthis.rowNum++;//獲取行號(hào)var curRowHeadCheckboxId = appData[i].name.split('_')[1];var childrenRow = this.childrenRow;if(!childrenRow.get(curRowHeadCheckboxId)) childrenRow.put(curRowHeadCheckboxId, []);this.addChildrenRow(appData[i].children);childrenRow.get(curRowHeadCheckboxId).push(curRowHeadCheckboxId);//加入當(dāng)前行if(appData[i].children) {//加入子行for(var j=0; j<appData[i].children.length; ++j) {var childCurRowHeadCheckboxId = appData[i].children[j].name.split('_')[1];var descendants = childrenRow.get(childCurRowHeadCheckboxId);//孫子們節(jié)點(diǎn)for(var k=0; k<descendants.length; ++k){childrenRow.get(curRowHeadCheckboxId).push(descendants[k]);}}}}}addDataPid(btnGroupColumns, appData) {//生成新的列, 并且為非表頭的每一個(gè)單元格設(shè)置固定 id,(防止表格渲染時(shí) id發(fā)生變化)if(!appData) return;for(var i=0; i<appData.length; ++i) {for(var j=0; j<btnGroupColumns.length; ++j) {if(!appData[i][btnGroupColumns[j].colname]) {appData[i][btnGroupColumns[j].colname] = btnGroupColumns[j].id + '_' + (++this.cid);//為這一行數(shù)據(jù)添加新的列//判斷應(yīng)用對(duì)應(yīng)的按鈕是否已經(jīng)選擇上, judgeDefaultCheckedif(appData[i].select && appData[i].select[btnGroupColumns[j].id]) {//btnGroupColumns[j].id == btnGroupIdthis.checkboxIdMapState.put(this.cid, true);} else {this.checkboxIdMapState.put(this.cid, false);}} else if(btnGroupColumns[j].colname == 'name'){if(appData[i][btnGroupColumns[j].colname].indexOf('_') >= 0) continue;appData[i][btnGroupColumns[j].colname] += '_' + (++this.cid);this.checkboxIdMapState.put(this.cid, false);}}this.addDataPid(btnGroupColumns, appData[i].children);}}addColName(btnGroupColumns, appData){if(btnGroupColumns) {btnGroupColumns.map((elem, index)=> { if(!elem.colname) {elem.colname = elem.id;}elem.cid = ++this.cid;});}if(appData) {this.addDataPid(btnGroupColumns, appData);/////清空數(shù)據(jù)var keySet = this.childrenRow.keySet();for(var key in keySet){if(this.childrenRow.get(keySet[key]) && this.childrenRow.get(keySet[key]).length)this.childrenRow.get(keySet[key]).length = 0;}/////總行數(shù)this.rowNum = 0;this.addChildrenRow(appData);++this.rowNum;/////判斷應(yīng)用對(duì)應(yīng)的checkbox是否選中,列頭對(duì)應(yīng)的checkbox是否選中this.checkGroupAndColumnState();}}addData(cid, checked){var curCheckboxData = this.checkboxIdMapData.get(cid);if(curCheckboxData) {var curQueueData = {roleId: this.props.roleId,btnGroupId: curCheckboxData.btnGroupId,appId: curCheckboxData.appId,};this.dataQueue.push(curQueueData);}}isGroupRow(cid){//判斷是否為分組//第一行當(dāng)做分組if(parseInt((cid-1)/this.colNum)*this.colNum+1 == 1) return true; const parentRow = this.parentRow;const childrenRow = this.childrenRow;var curRowHeadCheckboxId = parentRow.get(cid) ? parentRow.get(cid) : parseInt((cid-1)/this.colNum)*this.colNum+1;//通過cid 和 curRowHeadCheckboxId獲取到cid對(duì)應(yīng)的checkbox到左邊的距離var rowIds = childrenRow.get(curRowHeadCheckboxId);//所有子行的行頭的 checkboxIdreturn rowIds.length > 1 ? true : false;}checkGroupAndColumnState() {const childrenRow = this.childrenRow;const checkboxIdMapState = this.checkboxIdMapState;const colNum = this.colNum;const rowNum = this.rowNum;const rowState = [];for(var i=0; i<=rowNum; ++i)rowState.push(true)//默認(rèn)所有的行全選rowState[1] = false;for(var row=2; row <= rowNum; ++row) {var cb = (row-1)*colNum+2;//這一行從第2個(gè) checkbox 開始if(this.isGroupRow(cb)) {//分組行,不算入rowState[row] = false;continue;}var ce = row*colNum;var curRowState = true;//默認(rèn)這一行全選for(var cid=cb; cid<=ce; ++cid) {//遍歷這一行if(checkboxIdMapState.get(cid) == false) {curRowState = false;break;}}rowState[row] = curRowState;if(rowState[row] == true) {//應(yīng)用對(duì)應(yīng)的checkbox選中checkboxIdMapState.put((row-1)*colNum+1, true);} else {checkboxIdMapState.put((row-1)*colNum+1, false);}}//判斷分組是否選中for(var row=2; row <= rowNum; ++row) {const cid = (row-1)*colNum+1;//每一行的第一個(gè)if(!this.isGroupRow(cid)) continue;//計(jì)算分組行var cids = childrenRow.get(cid);var groupState = true;//默認(rèn)這個(gè)分組被選中for(var i=0; i<cids.length; ++i){if(cids[i] != cid) {//不是分組行var cur_row = (cids[i]-1)/this.colNum+1;if(rowState[cur_row] == false) {groupState = false;break;}}}for(var cur_cid=cid; cur_cid <= row*colNum; ++cur_cid){//當(dāng)前分組行的 checkbox 狀態(tài) checkboxIdMapState.put(cur_cid, groupState);}if(groupState == false) {//如果當(dāng)前分組行沒有狀態(tài)改變,查看這一行的某一個(gè)分組列是否有變化const childRowNum = cids.length-1;for(var curRowCid = cid; curRowCid<cid+this.colNum; ++curRowCid) {//遍歷這一分組行的checkboxIdvar curColState = true;for(var childRowCid = curRowCid+this.colNum, cnt = 0; cnt < childRowNum; childRowCid += this.colNum, ++cnt) {if(checkboxIdMapState.get(childRowCid) == false) {curColState = false;break;}}checkboxIdMapState.put(curRowCid, curColState);}}}// 判斷列 是否被選中if(rowNum > 1) {for(var col=1; col<=colNum; ++col) {var curColState = true;for(var cid=col+colNum; cid<=colNum*rowNum; cid+=colNum){if(checkboxIdMapState.get(cid) == false) {curColState = false;break;}}var cid = col;checkboxIdMapState.put(cid, curColState);//這一列的狀態(tài) }}}onChecked(cid, btnGroupId, appId, checked){//checkboxId, 按鈕id,應(yīng)用idconst checkboxIdMapState = this.checkboxIdMapState;const parentRow = this.parentRow;const parentCol = this.parentCol;const childrenRow = this.childrenRow;const colNum = this.colNum;const rowNum = this.rowNum;//清空數(shù)據(jù)隊(duì)列this.dataQueue.length = 0;//標(biāo)識(shí)當(dāng)前的操作this.checked = checked;if(btnGroupId == null && appId == null) {for(var cur_cid=1; cur_cid<=colNum*rowNum; ++cur_cid) {checkboxIdMapState.put(cur_cid, checked);if(!this.isGroupRow(cur_cid))this.addData(cur_cid, checked);}} else if(btnGroupId == null) {//appId 不為null, 這一行全選var rowHeadCheckboxIds = childrenRow.get(cid);//所有子行的行頭的 checkboxIdfor(var i=0; i<rowHeadCheckboxIds.length; ++i) {var cur_cid = rowHeadCheckboxIds[i];var cur_row_max_cid = parseInt(cur_cid) + colNum;while(cur_cid < cur_row_max_cid){checkboxIdMapState.put(cur_cid, checked);if(!this.isGroupRow(cur_cid))this.addData(cur_cid, checked);++cur_cid;}}} else if(appId == null) {//btnId不為null,這一列全部checkvar cur_cid = cid;while(cur_cid <= rowNum*colNum) {checkboxIdMapState.put(cur_cid, checked);if(!this.isGroupRow(cur_cid)) this.addData(cur_cid, checked);cur_cid += colNum;}} else {//都不為nullvar curRowHeadCheckboxId = parentRow.get(cid);//通過cid 和 curRowHeadCheckboxId獲取到cid對(duì)應(yīng)的checkbox到左邊的距離var rowIds = childrenRow.get(curRowHeadCheckboxId);//所有子行的行頭的 checkboxIdfor(var i=0; i<rowIds.length; ++i) {//這一列全部checkvar cur_cid = parseInt(rowIds[i]) + (cid-curRowHeadCheckboxId);checkboxIdMapState.put(cur_cid, checked);if(!this.isGroupRow(cur_cid))this.addData(cur_cid, checked);}}this.setState({});this.sendCheckData();//發(fā)送數(shù)據(jù) }//// render() {const appData = this.appData;const btnGroupColumns = this.btnGroupColumns;console.log(appData)let self = this;this.cid = 0;this.colNum = btnGroupColumns.length;//獲得列寬const checkboxIdMapState = this.checkboxIdMapState;const parentRow = this.parentRow;const parentCol = this.parentColif(btnGroupColumns) {this.addColName(btnGroupColumns, appData);//對(duì)應(yīng)用的數(shù)據(jù)進(jìn)行一個(gè)簡(jiǎn)單的處理 btnGroupColumns.map((elem, index)=> { //elem.colname=='name' ? null : elem.id, 默認(rèn)左上角的id 沒有 appId 和 btnGroupIdelem.title= <RoleCheckbox btnGroupId={elem.colname=='name' ? null : elem.id} appId={null} cid={elem.cid} onChecked={self.onChecked} checked={checkboxIdMapState.get(elem.cid)} title={elem.name}/>,elem.key = elem.dataIndex = elem.colname;elem.render = function(text, record, index){// text的值 == 對(duì)應(yīng)表頭列的Id == elem.idvar contents = text.split('_');text = contents[0];var cur_cid = contents[1];//當(dāng)前列頂端 checkboxId//判斷是否是第一列if(record.name.split('_')[0] != text) {//不是第一列var leftCheckBoxId = record.name.split('_')[1];parentRow.put(cur_cid, leftCheckBoxId);//該 checkboxId 對(duì)應(yīng)的 (應(yīng)用Id == leftCheckBoxId)//加入每個(gè)checkbox 要傳輸?shù)臄?shù)據(jù)(appId, btnGroupId) self.checkboxIdMapData.put(cur_cid, {appId: record.id, btnGroupId: elem.id})}//該 checkboxId 對(duì)應(yīng)的 最上邊的 checkboxIdparentCol.put(cur_cid, elem.cid);//該 checkboxId 對(duì)應(yīng)的 (按鈕Id == elem.cid)//record.name.split('_')[0] 最原始的 name 的valuereturn <RoleCheckbox btnGroupId={record.name.split('_')[0] == text ? null : elem.id} appId={record.id} cid={cur_cid} onChecked={self.onChecked} checked={checkboxIdMapState.get(cur_cid)} title={text==elem.id ? null : text}/> }});}return (<div><Btn iconName="icon-add" onClick={this.chooseApp} btnClass="add-btn" btnName="選擇應(yīng)用"/><Table indentSize={15}className="personType-table" columns={btnGroupColumns} dataSource={appData} pagination={false}/></div> );} } module.exports = RoleApplicationTable; RoleApplicationTable.propTypes = propTypes; module.exports = connect(mapStateToProps)(RoleApplicationTable); View Code

  利用antd table實(shí)現(xiàn)層級(jí)多選組件。

  具體思路:

addDataPid(btnGroupColumns, appData) {//生成新的列, 并且為非表頭的每一個(gè)單元格設(shè)置固定 id,(防止表格渲染時(shí) id發(fā)生變化)if(!appData) return;for(var i=0; i<appData.length; ++i) {for(var j=0; j<btnGroupColumns.length; ++j) {if(!appData[i][btnGroupColumns[j].colname]) {appData[i][btnGroupColumns[j].colname] = btnGroupColumns[j].id + '_' + (++this.cid);//為這一行數(shù)據(jù)添加新的列//判斷應(yīng)用對(duì)應(yīng)的按鈕是否已經(jīng)選擇上, judgeDefaultCheckedif(appData[i].select && appData[i].select[btnGroupColumns[j].id]) {//btnGroupColumns[j].id == btnGroupIdthis.checkboxIdMapState.put(this.cid, true);} else {this.checkboxIdMapState.put(this.cid, false);}} else if(btnGroupColumns[j].colname == 'name'){if(appData[i][btnGroupColumns[j].colname].indexOf('_') >= 0) continue;appData[i][btnGroupColumns[j].colname] += '_' + (++this.cid);this.checkboxIdMapState.put(this.cid, false);}}this.addDataPid(btnGroupColumns, appData[i].children);} }addColName(btnGroupColumns, appData){//為每一列添加 映射字段 colnameif(btnGroupColumns) {btnGroupColumns.map((elem, index)=> { if(!elem.colname) {elem.colname = elem.id;}elem.cid = ++this.cid;});}if(appData) {this.addDataPid(btnGroupColumns, appData);/////清空數(shù)據(jù)var keySet = this.childrenRow.keySet();for(var key in keySet){if(this.childrenRow.get(keySet[key]) && this.childrenRow.get(keySet[key]).length)this.childrenRow.get(keySet[key]).length = 0;}/////總行數(shù)this.rowNum = 0;this.addChildrenRow(appData);++this.rowNum;/////判斷應(yīng)用對(duì)應(yīng)的checkbox是否選中,列頭對(duì)應(yīng)的checkbox是否選中this.checkGroupAndColumnState();} }

?

  2.RoleCheckbox.js

import {Checkbox} from 'antd'; import React from 'react'; class RoleCheckbox extends React.Component{constructor(props) {super(props);this.onChange = this.onChange.bind(this);}onChange(e){const cid = this.props.cid;const btnGroupId = this.props.btnGroupId;const appId = this.props.appId;this.props.onChecked(cid, btnGroupId, appId, e.target.checked);}render() {const checked = this.props.checked;const title = this.props.title;const cid = this.props.cid;return(<div><Checkbox checked={checked} onChange={this.onChange}/>{title}</div> );} } module.exports = RoleCheckbox; View Code

?  封裝antd 的Checkbox組件

  3.Map.js

class Map {constructor(){this.container = new Object();}put(key, value){this.container[key] = value;}get(key){return this.container[key];}keySet() {var keyset = new Array();var count = 0;for (var key in this.container) {// 跳過object的extend函數(shù)if (key == 'extend') {continue;}keyset[count] = key;count++;}return keyset;}size() {var count = 0;for (var key in this.container) {// 跳過object的extend函數(shù)if (key == 'extend'){continue;}count++;}return count;}remove(key) {delete this.container[key];}toString(){var str = "";for (var i = 0, keys = this.keySet(), len = keys.length; i < len; i++) {str = str + keys[i] + "=" + this.container[keys[i]] + ";\n";}return str;} }module.exports = Map; View Code

  js實(shí)現(xiàn)的Map工具類。

?四、需求變更

  功能雖然完成了,但是總是避免不了需求的變更。要求選擇左邊應(yīng)用對(duì)應(yīng)的checkbox時(shí),不在操作該應(yīng)用對(duì)應(yīng)的按鈕的checkbox,也就是整個(gè)行不是全選了。應(yīng)用對(duì)應(yīng)的checkbox用來進(jìn)行刪除操作。

  1.改變后的Table效果

  

  2.RoleApplicationTable.js

import React from 'react'; import RoleCheckbox from 'components/role/RoleCheckbox'; import {Menu, Table, message, Modal} from 'antd'; const confirm = Modal.confirm; import Btn from 'components/public/BaseBtn'; import {connect} from 'react-redux'; import 'styles/less/personType.less'; import 'styles/less/basebtn.less'; import Map from 'components/role/Map'; import { operationRoleAppBtn, queryRoleAppBtnData, deleteAppAction} from 'actions/role';var mapStateToProps = function(state){return {roleData: state.getRole } }; //規(guī)范屬性類型 var propTypes = {personTypes: React.PropTypes.object,dispatch : React.PropTypes.func }; class RoleApplicationTable extends React.Component {constructor(props) {super(props);this.state = {isEdit: true,};this.chooseApp = this.chooseApp.bind(this);this.addColName = this.addColName.bind(this);this.addDataPid = this.addDataPid.bind(this);this.onChecked = this.onChecked.bind(this);this.addChildrenRow = this.addChildrenRow.bind(this);this.addAppBtnData = this.addAppBtnData.bind(this);this.addAppData = this.addAppData.bind(this);this.isGroupRow = this.isGroupRow.bind(this);this.checkGroupAndColumnState = this.checkGroupAndColumnState.bind(this);//確保 組全選 和 列 全選this.deleteApp = this.deleteApp.bind(this);this.showConfirm = this.showConfirm.bind(this);this.initRoleAppBtnData = this.initRoleAppBtnData.bind(this);this.cancelChooseState = this.cancelChooseState.bind(this);this.saveCheckedAppBtn = this.saveCheckedAppBtn.bind(this);this.afterSaveCheckedAppBtn = this.afterSaveCheckedAppBtn.bind(this);this.cid = 0;this.rowNum = 0;this.colNum = 0;//mapthis.checkboxIdMapState= new Map();//checkboxId 映射 Statethis.parentRow = new Map();//每個(gè)checkboxId節(jié)點(diǎn) 對(duì)應(yīng)最左邊的哪個(gè)應(yīng)用this.parentCol = new Map();//每個(gè)checkboxId節(jié)點(diǎn) 對(duì)應(yīng)最上邊的哪個(gè)按鈕this.childrenRow = new Map();//當(dāng)前行的所有子行this.checkboxIdMapAppBtnData = new Map();//每個(gè)checkbox對(duì)應(yīng)的 appid,btnGroupIdthis.checkboxIdMapAppData = new Map();//記錄被選中的應(yīng)用//保存數(shù)據(jù)this.dataQueue = [];// appid,btngroupId隊(duì)列//刪除應(yīng)用this.deleteAppIds = [];//測(cè)試數(shù)據(jù)this.appData = [{name: '報(bào)表',id: "456",key: '5', children: [{ name: '合同價(jià)款', id: "45xx61", key: '6', },{ name: '合同臺(tái)賬', id: "45xf61", key: '7', }], }, { name: '圖標(biāo)', id: "789", key: '1', children: [{ name: '小圖標(biāo)', id: "45xx60", key: '4' },{ name: '大圖標(biāo)', id: "4xx560", key: '8' }] }];this.btnGroupColumns = [{id: '12xx3', name: '小部件', colname: 'name'}, {id:'43xx5', name:'顯示'}, {id:'43xfffx5', name:'test'}];}//確認(rèn)提示框 showConfirm(title,message,dispatch,functionT,functionQueryData) {confirm({title: title,content: message,onOk() {dispatch(functionT(functionQueryData)); },onCancel() {}});}componentDidMount() {//const roleId = '4028968156b025da0156b027d0180000';this.initRoleAppBtnData();}initRoleAppBtnData(){const roleId = this.props.roleId;if(roleId) {//通過角色id加載 數(shù)據(jù)const { dispatch } = this.props;const querydata = {roleId: roleId};dispatch(queryRoleAppBtnData(querydata));}}cancelChooseState(){//取消權(quán)限的更改this.initRoleAppBtnData();}componentWillReceiveProps(nextProps) {const {roleData} = nextProps;if (roleData.msg) {if(roleData.msg.indexOf('成功') >= 0)message.success(roleData.msg, 5);else if(roleData.msg.indexOf('失敗') >= 0)message.error(roleData.msg, 5);else message.info(roleData.msg, 5);// if (roleData.msg == '保存成功') {//角色保存成功后 仍然留在當(dāng)前頁面, 繼續(xù) 角色按鈕組權(quán)限// this.props.history.pushState(null, 'rolecenter');// } }}chooseApp(){this.props.chooseApp();}sendCheckData(){const { dispatch } = this.props;const queryData = {'vos': this.dataQueue,//對(duì)應(yīng)后端的字段'roleId': this.props.roleId,};dispatch(operationRoleAppBtn(queryData, this.afterSaveCheckedAppBtn));}//// addChildrenRow(appData){//添加所有子行 標(biāo)識(shí)if(!appData) return;for(var i=0; i<appData.length; ++i) {//獲取行頭的checkboxIdthis.rowNum++;//獲取行號(hào)var curRowHeadCheckboxId = appData[i].name.split('_')[1];var childrenRow = this.childrenRow;if(!childrenRow.get(curRowHeadCheckboxId)) childrenRow.put(curRowHeadCheckboxId, []);this.addChildrenRow(appData[i].children);childrenRow.get(curRowHeadCheckboxId).push(curRowHeadCheckboxId);//加入當(dāng)前行if(appData[i].children) {//加入子行for(var j=0; j<appData[i].children.length; ++j) {var childCurRowHeadCheckboxId = appData[i].children[j].name.split('_')[1];var descendants = childrenRow.get(childCurRowHeadCheckboxId);//孫子們節(jié)點(diǎn)for(var k=0; k<descendants.length; ++k){childrenRow.get(curRowHeadCheckboxId).push(descendants[k]);}}}}}addDataPid(btnGroupColumns, appData) {//生成新的列, 并且為非表頭的每一個(gè)單元格設(shè)置固定 id,(防止表格渲染時(shí) id發(fā)生變化)if(!appData) return;for(var i=0; i<appData.length; ++i) {for(var j=0; j<btnGroupColumns.length; ++j) {if(!appData[i][btnGroupColumns[j].colname]) {appData[i][btnGroupColumns[j].colname] = btnGroupColumns[j].id + '_' + (++this.cid);//為這一行數(shù)據(jù)添加新的列//判斷應(yīng)用對(duì)應(yīng)的按鈕是否已經(jīng)選擇上, judgeDefaultCheckedif(appData[i].select && appData[i].select[btnGroupColumns[j].id]) {//btnGroupColumns[j].id == btnGroupIdthis.checkboxIdMapState.put(this.cid, true);} else {this.checkboxIdMapState.put(this.cid, false);}} else if(btnGroupColumns[j].colname == 'name'){if(appData[i][btnGroupColumns[j].colname].indexOf('_') >= 0) continue;appData[i][btnGroupColumns[j].colname] += '_' + (++this.cid);this.checkboxIdMapState.put(this.cid, false);}}this.addDataPid(btnGroupColumns, appData[i].children);}}addColName(btnGroupColumns, appData){if(btnGroupColumns) {btnGroupColumns.map((elem, index)=> { if(!elem.colname) {elem.colname = elem.id;}elem.cid = ++this.cid;});}if(appData) {this.addDataPid(btnGroupColumns, appData);/////清空數(shù)據(jù)var keySet = this.childrenRow.keySet();for(var key in keySet){if(this.childrenRow.get(keySet[key]) && this.childrenRow.get(keySet[key]).length)this.childrenRow.get(keySet[key]).length = 0;}/////總行數(shù)this.rowNum = 0;this.addChildrenRow(appData);++this.rowNum;/////判斷應(yīng)用對(duì)應(yīng)的checkbox是否選中,列頭對(duì)應(yīng)的checkbox是否選中this.checkGroupAndColumnState();}}addAppBtnData(cid){var curCheckboxData = this.checkboxIdMapAppBtnData.get(cid);if(curCheckboxData) {var curQueueData = {roleId: this.props.roleId,btnGroupId: curCheckboxData.btnGroupId,appId: curCheckboxData.appId,};this.dataQueue.push(curQueueData);}}addAppData(cid){var checked = this.checkboxIdMapState.get(cid);if(checked == false) return;var curAppId = this.checkboxIdMapAppData.get(cid);if(curAppId) {var curQueueData = {roleId: this.props.roleId,appId: curAppId,};this.deleteAppIds.push(curQueueData);}}isGroupRow(cid){//判斷是否為分組//第一行當(dāng)做分組if(parseInt((cid-1)/this.colNum)*this.colNum+1 == 1) return true; const parentRow = this.parentRow;const childrenRow = this.childrenRow;var curRowHeadCheckboxId = parentRow.get(cid) ? parentRow.get(cid) : parseInt((cid-1)/this.colNum)*this.colNum+1;//通過cid 和 curRowHeadCheckboxId獲取到cid對(duì)應(yīng)的checkbox到左邊的距離var rowIds = childrenRow.get(curRowHeadCheckboxId);//所有子行的行頭的 checkboxIdreturn rowIds.length > 1 ? true : false;}checkGroupAndColumnState() {const childrenRow = this.childrenRow;const checkboxIdMapState = this.checkboxIdMapState;const colNum = this.colNum;const rowNum = this.rowNum;const rowState = [];for(var i=0; i<=rowNum; ++i)rowState.push(true)//默認(rèn)所有的行全選rowState[1] = false;//判斷分組列for(var row=2; row <= rowNum; ++row) {const cid = (row-1)*colNum+1;//每一行的第一個(gè)if(!this.isGroupRow(cid)) continue;var cids = childrenRow.get(cid);const childRowNum = cids.length-1;for(var curRowCid = cid; curRowCid<cid+this.colNum; ++curRowCid) {//遍歷這一分組行的checkboxIdvar curColState = true;for(var childRowCid = curRowCid+this.colNum, cnt = 0; cnt < childRowNum; childRowCid += this.colNum, ++cnt) {if(checkboxIdMapState.get(childRowCid) == false) {curColState = false;break;}}checkboxIdMapState.put(curRowCid, curColState);}}// 判斷列 是否被選中if(rowNum > 1) {for(var col=1; col<=colNum; ++col) {var curColState = true;for(var cid=col+colNum; cid<=colNum*rowNum; cid+=colNum){if(checkboxIdMapState.get(cid) == false) {curColState = false;break;}}var cid = col;checkboxIdMapState.put(cid, curColState);//這一列的狀態(tài) }} else if(rowNum == 1) {//每一列的狀態(tài)清空for(var cid = 1; cid <= this.colNum; ++cid)checkboxIdMapState.put(cid, false);}}onChecked(cid, btnGroupId, appId, checked){//checkboxId, 按鈕id,應(yīng)用idif(this.state.isEdit == true && cid%this.colNum != 1) {//第一列為應(yīng)用列,隨時(shí)可以編輯message.info('請(qǐng)進(jìn)入編輯狀態(tài)', 2);return ;}const checkboxIdMapState = this.checkboxIdMapState;const parentRow = this.parentRow;const parentCol = this.parentCol;const childrenRow = this.childrenRow;const colNum = this.colNum;const rowNum = this.rowNum;if(btnGroupId == null && appId == null) {for(var cur_cid=1; cur_cid<=colNum*rowNum; cur_cid+=colNum) {checkboxIdMapState.put(cur_cid, checked);}} else if(btnGroupId == null) {//appId 不為null, 所有的子應(yīng)用全選var rowHeadCheckboxIds = childrenRow.get(cid);//所有子行的行頭的 checkboxId(對(duì)應(yīng)應(yīng)用)for(var i=0; i<rowHeadCheckboxIds.length; ++i) {var cur_cid = rowHeadCheckboxIds[i];checkboxIdMapState.put(cur_cid, checked);}} else if(appId == null) {//btnId不為null,這一列全部checkvar cur_cid = cid;while(cur_cid <= rowNum*colNum) {checkboxIdMapState.put(cur_cid, checked);cur_cid += colNum;}} else {//都不為nullvar curRowHeadCheckboxId = parentRow.get(cid);//通過cid 和 curRowHeadCheckboxId獲取到cid對(duì)應(yīng)的checkbox到左邊的距離var rowIds = childrenRow.get(curRowHeadCheckboxId);//所有子行的行頭的 checkboxIdfor(var i=0; i<rowIds.length; ++i) {//這一列全部checkvar cur_cid = parseInt(rowIds[i]) + (cid-curRowHeadCheckboxId);checkboxIdMapState.put(cur_cid, checked);}}this.setState({});}deleteApp(){this.deleteAppIds.length = 0;//清空數(shù)據(jù)const {dispatch} = this.props;for(var cid = 1; cid <= this.rowNum*this.colNum; cid += this.colNum) {if(!this.isGroupRow(cid)) {this.addAppData(cid);}}if(this.deleteAppIds.length == 0) {message.success('請(qǐng)選擇應(yīng)用', 5);return;}const queryData = {vos: this.deleteAppIds,}this.showConfirm('刪除應(yīng)用', '確定刪除應(yīng)用?', dispatch, deleteAppAction, queryData); }afterSaveCheckedAppBtn(){this.setState({isEdit: true,});}saveCheckedAppBtn(){if(this.state.isEdit == true) {this.setState({isEdit: false,});return ;} //清空數(shù)據(jù)隊(duì)列this.dataQueue.length = 0;for(var cid = this.colNum+1; cid <= this.colNum*this.rowNum; ++cid) {//從第二行的checkbox 開始if(this.isGroupRow(cid)) {cid += this.colNum;}if(cid%this.colNum != 1) {//第一列為 應(yīng)用列if(this.checkboxIdMapState.get(cid) == true)this.addAppBtnData(cid);}}this.sendCheckData();}//// render() {let {roleData} = this.props;var appData = [];var btnGroupColumns = [];if(roleData.permissiondData) {if(roleData.permissiondData.listAppBtnGroup) {btnGroupColumns = roleData.permissiondData.listAppBtnGroup;}if(roleData.permissiondData.listPermissionApp) {appData = roleData.permissiondData.listPermissionApp;}}// const appData = this.appData;// const btnGroupColumns = this.btnGroupColumns;// console.log(appData)let self = this;this.cid = 0;this.colNum = btnGroupColumns.length;//獲得列寬const checkboxIdMapState = this.checkboxIdMapState;const parentRow = this.parentRow;const parentCol = this.parentColif(btnGroupColumns) {this.addColName(btnGroupColumns, appData);//對(duì)應(yīng)用的數(shù)據(jù)進(jìn)行一個(gè)簡(jiǎn)單的處理 btnGroupColumns.map((elem, index)=> { //elem.colname=='name' ? null : elem.id, 默認(rèn)左上角的id 沒有 appId 和 btnGroupIdelem.title= <RoleCheckbox btnGroupId={elem.colname=='name' ? null : elem.id} appId={null} cid={elem.cid} onChecked={self.onChecked} checked={checkboxIdMapState.get(elem.cid)} title={elem.name}/>,elem.key = elem.dataIndex = elem.colname;elem.render = function(text, record, index){// text的值 == 對(duì)應(yīng)表頭列的Id == elem.idvar contents = text.split('_');text = contents[0];var cur_cid = contents[1];//當(dāng)前列頂端 checkboxId//判斷是否是第一列if(record.name.split('_')[0] != text) {//不是第一列var leftCheckBoxId = record.name.split('_')[1];parentRow.put(cur_cid, leftCheckBoxId);//該 checkboxId 對(duì)應(yīng)的 (應(yīng)用Id == leftCheckBoxId)//加入每個(gè)checkbox 要傳輸?shù)臄?shù)據(jù)(appId, btnGroupId) self.checkboxIdMapAppBtnData.put(cur_cid, {appId: record.id, btnGroupId: elem.id})} else {//應(yīng)用列 self.checkboxIdMapAppData.put(cur_cid, record.id);}//該 checkboxId 對(duì)應(yīng)的 最上邊的 checkboxIdparentCol.put(cur_cid, elem.cid);//該 checkboxId 對(duì)應(yīng)的 (按鈕Id == elem.cid)//record.name.split('_')[0] 最原始的 name 的valuereturn <RoleCheckbox btnGroupId={record.name.split('_')[0] == text ? null : elem.id} appId={record.id} cid={cur_cid} onChecked={self.onChecked} checked={checkboxIdMapState.get(cur_cid)} title={text==elem.id ? null : text}/> }});}return (<div><Btn iconName="icon-add" isdisabled={self.props.roleId ? false : true} onClick={this.chooseApp} btnClass="add-btn" btnName="選擇應(yīng)用"/>&nbsp;&nbsp;&nbsp;&nbsp;<Btn iconName="icon-jianhao" isdisabled={self.props.roleId ? false : true} btnClass="delete-btn" btnName="刪除應(yīng)用" onClick={self.deleteApp}/> <Table style={{marginTop: "10px", marginBottom: "10px"}}indentSize={15}className="personType-table" columns={btnGroupColumns} dataSource={appData} pagination={false}/><div style={{display: self.rowNum > 1 ? '' : 'none'}}><Btn btnClass="save-btn" btnName={self.state.isEdit == true ? "編輯" : "保存"} onClick={this.saveCheckedAppBtn}/>&nbsp;&nbsp;&nbsp;&nbsp;<Btn btnClass="cancel-btn" btnName="取消" onClick={self.cancelChooseState}/></div></div> );} } module.exports = RoleApplicationTable; RoleApplicationTable.propTypes = propTypes; module.exports = connect(mapStateToProps)(RoleApplicationTable); View Code

五、心得體會(huì)

  最近使用react + redux + webpack進(jìn)行web開發(fā),感覺進(jìn)步很快,已經(jīng)熟悉了基本的流程。后續(xù)要研究一下webpack。

轉(zhuǎn)載于:https://www.cnblogs.com/hujunzheng/p/5812046.html

總結(jié)

以上是生活随笔為你收集整理的React使用antd Table生成层级多选组件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。