用戶對不一樣的應用須要有不一樣的權限,用戶通常和角色關聯在一塊兒,新建角色的時候會選擇該角色對應的應用,而後對應用分配權限。因而寫了一種實現的方式。首先應用是一個二級樹,一級表示的是應用分組,二級表示的是應用,這是table的最左邊的數據。而後是按鈕的數據,這裏顯示在table的頭部。react
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 } }; //規範屬性類型 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; //map this.checkboxIdMapState= new Map();//checkboxId 映射 State this.parentRow = new Map();//每一個checkboxId節點 對應最左邊的哪一個應用 this.parentCol = new Map();//每一個checkboxId節點 對應最上邊的哪一個按鈕 this.childrenRow = new Map();//當前行的全部子行 this.checkboxIdMapData = new Map();//每一個checkbox對應的 appid,btnGroupId //保存數據 this.checked = null;//標識數據是 新增 仍是 刪除 this.dataQueue = [];// appid,btngroupId隊列 //測試數據 this.appData = [{name: '報表',id: "456",key: '5', children: [{ name: '合同價款', id: "45xx61", key: '6', },{ name: '合同臺帳', id: "45xf61", key: '7', }], }, { name: '圖標', id: "789", key: '1', children: [{ name: '小圖標', id: "45xx60", key: '4' },{ name: '大圖標', 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加載 數據 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 == '保存成功') {//角色保存成功後 仍然留在當前頁面, 繼續 角色按鈕組權限 // this.props.history.pushState(null, 'rolecenter'); // } } } chooseApp(){ this.props.chooseApp(); } sendCheckData(){ const { dispatch } = this.props; const queryData = { vos: this.dataQueue,//對應後端的字段 }; dispatch(operationRoleAppBtn(this.checked, queryData)); } //////////////////////////////////////////////////////////////////////////////// addChildrenRow(appData){//添加全部子行 標識 if(!appData) return; for(var i=0; i<appData.length; ++i) {//獲取行頭的checkboxId this.rowNum++;//獲取行號 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);//加入當前行 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);//孫子們節點 for(var k=0; k<descendants.length; ++k){ childrenRow.get(curRowHeadCheckboxId).push(descendants[k]); } } } } } addDataPid(btnGroupColumns, appData) {//生成新的列, 而且爲非表頭的每個單元格設置固定 id,(防止表格渲染時 id發生變化) 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);//爲這一行數據添加新的列 //判斷應用對應的按鈕是否已經選擇上, judgeDefaultChecked if(appData[i].select && appData[i].select[btnGroupColumns[j].id]) {//btnGroupColumns[j].id == btnGroupId this.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); /////清空數據 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; } /////總行數 this.rowNum = 0; this.addChildrenRow(appData); ++this.rowNum; /////判斷應用對應的checkbox是否選中,列頭對應的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){//判斷是否爲分組 //第一行當作分組 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對應的checkbox到左邊的距離 var rowIds = childrenRow.get(curRowHeadCheckboxId);//全部子行的行頭的 checkboxId return 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)//默認全部的行全選 rowState[1] = false; for(var row=2; row <= rowNum; ++row) { var cb = (row-1)*colNum+2;//這一行從第2個 checkbox 開始 if(this.isGroupRow(cb)) {//分組行,不算入 rowState[row] = false; continue; } var ce = row*colNum; var curRowState = true;//默認這一行全選 for(var cid=cb; cid<=ce; ++cid) {//遍歷這一行 if(checkboxIdMapState.get(cid) == false) { curRowState = false; break; } } rowState[row] = curRowState; if(rowState[row] == true) {//應用對應的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;//每一行的第一個 if(!this.isGroupRow(cid)) continue; //計算分組行 var cids = childrenRow.get(cid); var groupState = true;//默認這個分組被選中 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){//當前分組行的 checkbox 狀態 checkboxIdMapState.put(cur_cid, groupState); } if(groupState == false) {//若是當前分組行沒有狀態改變,查看這一行的某一個分組列是否有變化 const childRowNum = cids.length-1; for(var curRowCid = cid; curRowCid<cid+this.colNum; ++curRowCid) {//遍歷這一分組行的checkboxId var 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);//這一列的狀態 } } } onChecked(cid, btnGroupId, appId, checked){//checkboxId, 按鈕id,應用id const checkboxIdMapState = this.checkboxIdMapState; const parentRow = this.parentRow; const parentCol = this.parentCol; const childrenRow = this.childrenRow; const colNum = this.colNum; const rowNum = this.rowNum; //清空數據隊列 this.dataQueue.length = 0; //標識當前的操做 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);//全部子行的行頭的 checkboxId for(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,這一列所有check var 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 {//都不爲null var curRowHeadCheckboxId = parentRow.get(cid);//經過cid 和 curRowHeadCheckboxId獲取到cid對應的checkbox到左邊的距離 var rowIds = childrenRow.get(curRowHeadCheckboxId);//全部子行的行頭的 checkboxId for(var i=0; i<rowIds.length; ++i) {//這一列所有check var 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();//發送數據 } //////////////////////////////////////////////////////////////////////////////// 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.parentCol if(btnGroupColumns) { this.addColName(btnGroupColumns, appData);//對應用的數據進行一個簡單的處理 btnGroupColumns.map((elem, index)=> { //elem.colname=='name' ? null : elem.id, 默認左上角的id 沒有 appId 和 btnGroupId elem.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的值 == 對應表頭列的Id == elem.id var contents = text.split('_'); text = contents[0]; var cur_cid = contents[1];//當前列頂端 checkboxId //判斷是不是第一列 if(record.name.split('_')[0] != text) {//不是第一列 var leftCheckBoxId = record.name.split('_')[1]; parentRow.put(cur_cid, leftCheckBoxId);//該 checkboxId 對應的 (應用Id == leftCheckBoxId) //加入每一個checkbox 要傳輸的數據(appId, btnGroupId) self.checkboxIdMapData.put(cur_cid, {appId: record.id, btnGroupId: elem.id}) } //該 checkboxId 對應的 最上邊的 checkboxId parentCol.put(cur_cid, elem.cid);//該 checkboxId 對應的 (按鈕Id == elem.cid) //record.name.split('_')[0] 最原始的 name 的value return <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="選擇應用"/> <Table indentSize={15} className="personType-table" columns={btnGroupColumns} dataSource={appData} pagination={false} /> </div> ); } } module.exports = RoleApplicationTable; RoleApplicationTable.propTypes = propTypes; module.exports = connect(mapStateToProps)(RoleApplicationTable);
利用antd table實現層級多選組件。webpack
具體思路:web
addDataPid(btnGroupColumns, appData) {//生成新的列, 而且爲非表頭的每個單元格設置固定 id,(防止表格渲染時 id發生變化) 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);//爲這一行數據添加新的列 //判斷應用對應的按鈕是否已經選擇上, judgeDefaultChecked if(appData[i].select && appData[i].select[btnGroupColumns[j].id]) {//btnGroupColumns[j].id == btnGroupId this.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){//爲每一列添加 映射字段 colname if(btnGroupColumns) { btnGroupColumns.map((elem, index)=> { if(!elem.colname) { elem.colname = elem.id; } elem.cid = ++this.cid; }); } if(appData) { this.addDataPid(btnGroupColumns, appData); /////清空數據 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; } /////總行數 this.rowNum = 0; this.addChildrenRow(appData); ++this.rowNum; /////判斷應用對應的checkbox是否選中,列頭對應的checkbox是否選中 this.checkGroupAndColumnState(); } }
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;
封裝antd 的Checkbox組件redux
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函數 if (key == 'extend') { continue; } keyset[count] = key; count++; } return keyset; } size() { var count = 0; for (var key in this.container) { // 跳過object的extend函數 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;
js實現的Map工具類。後端
功能雖然完成了,可是老是避免不了需求的變動。要求選擇左邊應用對應的checkbox時,不在操做該應用對應的按鈕的checkbox,也就是整個行不是全選了。應用對應的checkbox用來進行刪除操做。antd
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 } }; //規範屬性類型 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; //map this.checkboxIdMapState= new Map();//checkboxId 映射 State this.parentRow = new Map();//每一個checkboxId節點 對應最左邊的哪一個應用 this.parentCol = new Map();//每一個checkboxId節點 對應最上邊的哪一個按鈕 this.childrenRow = new Map();//當前行的全部子行 this.checkboxIdMapAppBtnData = new Map();//每一個checkbox對應的 appid,btnGroupId this.checkboxIdMapAppData = new Map();//記錄被選中的應用 //保存數據 this.dataQueue = [];// appid,btngroupId隊列 //刪除應用 this.deleteAppIds = []; //測試數據 this.appData = [{name: '報表',id: "456",key: '5', children: [{ name: '合同價款', id: "45xx61", key: '6', },{ name: '合同臺帳', id: "45xf61", key: '7', }], }, { name: '圖標', id: "789", key: '1', children: [{ name: '小圖標', id: "45xx60", key: '4' },{ name: '大圖標', id: "4xx560", key: '8' }] }]; this.btnGroupColumns = [{id: '12xx3', name: '小部件', colname: 'name'}, {id:'43xx5', name:'顯示'}, {id:'43xfffx5', name:'test'}]; } //確認提示框 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加載 數據 const { dispatch } = this.props; const querydata = {roleId: roleId}; dispatch(queryRoleAppBtnData(querydata)); } } cancelChooseState(){//取消權限的更改 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 == '保存成功') {//角色保存成功後 仍然留在當前頁面, 繼續 角色按鈕組權限 // this.props.history.pushState(null, 'rolecenter'); // } } } chooseApp(){ this.props.chooseApp(); } sendCheckData(){ const { dispatch } = this.props; const queryData = { 'vos': this.dataQueue,//對應後端的字段 'roleId': this.props.roleId, }; dispatch(operationRoleAppBtn(queryData, this.afterSaveCheckedAppBtn)); } //////////////////////////////////////////////////////////////////////////////// addChildrenRow(appData){//添加全部子行 標識 if(!appData) return; for(var i=0; i<appData.length; ++i) {//獲取行頭的checkboxId this.rowNum++;//獲取行號 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);//加入當前行 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);//孫子們節點 for(var k=0; k<descendants.length; ++k){ childrenRow.get(curRowHeadCheckboxId).push(descendants[k]); } } } } } addDataPid(btnGroupColumns, appData) {//生成新的列, 而且爲非表頭的每個單元格設置固定 id,(防止表格渲染時 id發生變化) 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);//爲這一行數據添加新的列 //判斷應用對應的按鈕是否已經選擇上, judgeDefaultChecked if(appData[i].select && appData[i].select[btnGroupColumns[j].id]) {//btnGroupColumns[j].id == btnGroupId this.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); /////清空數據 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; } /////總行數 this.rowNum = 0; this.addChildrenRow(appData); ++this.rowNum; /////判斷應用對應的checkbox是否選中,列頭對應的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){//判斷是否爲分組 //第一行當作分組 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對應的checkbox到左邊的距離 var rowIds = childrenRow.get(curRowHeadCheckboxId);//全部子行的行頭的 checkboxId return 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)//默認全部的行全選 rowState[1] = false; //判斷分組列 for(var row=2; row <= rowNum; ++row) { const cid = (row-1)*colNum+1;//每一行的第一個 if(!this.isGroupRow(cid)) continue; var cids = childrenRow.get(cid); const childRowNum = cids.length-1; for(var curRowCid = cid; curRowCid<cid+this.colNum; ++curRowCid) {//遍歷這一分組行的checkboxId var 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);//這一列的狀態 } } else if(rowNum == 1) {//每一列的狀態清空 for(var cid = 1; cid <= this.colNum; ++cid) checkboxIdMapState.put(cid, false); } } onChecked(cid, btnGroupId, appId, checked){//checkboxId, 按鈕id,應用id if(this.state.isEdit == true && cid%this.colNum != 1) {//第一列爲應用列,隨時能夠編輯 message.info('請進入編輯狀態', 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, 全部的子應用全選 var rowHeadCheckboxIds = childrenRow.get(cid);//全部子行的行頭的 checkboxId(對應應用) for(var i=0; i<rowHeadCheckboxIds.length; ++i) { var cur_cid = rowHeadCheckboxIds[i]; checkboxIdMapState.put(cur_cid, checked); } } else if(appId == null) {//btnId不爲null,這一列所有check var cur_cid = cid; while(cur_cid <= rowNum*colNum) { checkboxIdMapState.put(cur_cid, checked); cur_cid += colNum; } } else {//都不爲null var curRowHeadCheckboxId = parentRow.get(cid);//經過cid 和 curRowHeadCheckboxId獲取到cid對應的checkbox到左邊的距離 var rowIds = childrenRow.get(curRowHeadCheckboxId);//全部子行的行頭的 checkboxId for(var i=0; i<rowIds.length; ++i) {//這一列所有check var cur_cid = parseInt(rowIds[i]) + (cid-curRowHeadCheckboxId); checkboxIdMapState.put(cur_cid, checked); } } this.setState({}); } deleteApp(){ this.deleteAppIds.length = 0;//清空數據 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('請選擇應用', 5); return; } const queryData = { vos: this.deleteAppIds, } this.showConfirm('刪除應用', '肯定刪除應用?', dispatch, deleteAppAction, queryData); } afterSaveCheckedAppBtn(){ this.setState({ isEdit: true, }); } saveCheckedAppBtn(){ if(this.state.isEdit == true) { this.setState({ isEdit: false, }); return ; } //清空數據隊列 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) {//第一列爲 應用列 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.parentCol if(btnGroupColumns) { this.addColName(btnGroupColumns, appData);//對應用的數據進行一個簡單的處理 btnGroupColumns.map((elem, index)=> { //elem.colname=='name' ? null : elem.id, 默認左上角的id 沒有 appId 和 btnGroupId elem.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的值 == 對應表頭列的Id == elem.id var contents = text.split('_'); text = contents[0]; var cur_cid = contents[1];//當前列頂端 checkboxId //判斷是不是第一列 if(record.name.split('_')[0] != text) {//不是第一列 var leftCheckBoxId = record.name.split('_')[1]; parentRow.put(cur_cid, leftCheckBoxId);//該 checkboxId 對應的 (應用Id == leftCheckBoxId) //加入每一個checkbox 要傳輸的數據(appId, btnGroupId) self.checkboxIdMapAppBtnData.put(cur_cid, {appId: record.id, btnGroupId: elem.id}) } else {//應用列 self.checkboxIdMapAppData.put(cur_cid, record.id); } //該 checkboxId 對應的 最上邊的 checkboxId parentCol.put(cur_cid, elem.cid);//該 checkboxId 對應的 (按鈕Id == elem.cid) //record.name.split('_')[0] 最原始的 name 的value return <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="選擇應用"/> <Btn iconName="icon-jianhao" isdisabled={self.props.roleId ? false : true} btnClass="delete-btn" btnName="刪除應用" 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}/> <Btn btnClass="cancel-btn" btnName="取消" onClick={self.cancelChooseState}/> </div> </div> ); } } module.exports = RoleApplicationTable; RoleApplicationTable.propTypes = propTypes; module.exports = connect(mapStateToProps)(RoleApplicationTable);
最近使用react + redux + webpack進行web開發,感受進步很快,已經熟悉了基本的流程。後續要研究一下webpack。app