项目要求做个权限的设定功能,
其中的企业,审批,供应商相当于该行中的全选按钮,选中的话其同行的其他项也要被选中,而这些权限菜单是通过后台接口获取的数据,数据结构如下:
[
{
"children": [
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 5,
"name": "组织架构",
"parentid": 1,
"sort": 10,
"state": "",
"is_checked": true
},
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 6,
"name": "员工管理",
"parentid": 1,
"sort": 20,
"state": "",
"is_checked": true
},
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 11,
"name": "角色管理",
"parentid": 1,
"sort": 30,
"state": "",
"is_checked": false
},
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 17,
"name": "企业设置",
"parentid": 1,
"sort": 2,
"state": "",
"is_checked": true
},
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 26,
"name": "员工管理",
"parentid": 1,
"sort": 1,
"state": "",
"is_checked": false
}
],
"hasChildren": true,
"is_admin": 1,
"menuid": 1,
"name": "企业",
"parentid": 0,
"sort": 20,
"state": "closed",
"is_checked": true
},
{
"children": [
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 12,
"name": "供应商订单",
"parentid": 4,
"sort": 10,
"state": "",
"is_checked": true
},
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 15,
"name": "供应商管理",
"parentid": 4,
"sort": 20,
"state": "",
"is_checked": false
},
{
"children": [],
"hasChildren": false,
"is_admin": 1,
"menuid": 16,
"name": "成为供应商",
"parentid": 4,
"sort": 30,
"state": "",
"is_checked": true
}
],
"hasChildren": true,
"is_admin": 1,
"menuid": 4,
"name": "供应商",
"parentid": 0,
"sort": 11,
"state": "closed",
"is_checked": true
}
]
刚开始使用map,render出来结构
{
authorityList.map((item,key) => {
console.log(item.is_checked)
return (
<div key={key} >
<Checkbox key={key} defaultChecked={item.is_checked} name={`group_${key}`} value={item.menuid} onChange={(e)=>this.selectCheckbox(e)}>{item.name}</Checkbox >
{
item.hasChildren ?
<div >
{
item.children.map((sub, subKey) => {
return <Checkbox name= defaultChecked={sub.is_checked} value={sub.menuid} id={`${sub.menuid}`} key={subKey} onChange={(e)=>this.selectCheckbox(e)}>{sub.name}</Checkbox >
})
}
</div > : null
}
</div >
)
})
}
可以渲染出来初始数据,但是在定义全选事件的时候除了原生自带的加判断就不知道如何写了,所以后期改为应用Checkbox.Group这个组件,但是应用这个组件的时候其自带的OnChange事件只能传递选中的值而无法传其他的key,纠结~
后期终于解决,代码如下:
先用modal从后台获取数据:
*getAuthorityList({ payload }, { call, put, select }){
const { data } = yield call(api.authorityList, queryString.stringify(payload));
if (data.result === 0) {
window.toast(data.message);
} else {
let menuList=data.menu_list;
let newList=[];
menuList.map((item,key)=> {
let checkAll=item.is_checked;
let checkAllId=item.menuid;
// let indeterminate=item.is_checked;
let checkedList=[];
let allListId=[];
if(item.hasChildren){
item.children.map((subItem,subKey)=> {
allListId.push(subItem.menuid)
if(subItem.is_checked){
checkedList.push(subItem.menuid)
}
})
}
let obj={
['checkAll'+key]:checkAll,
['checkAllId'+key]:checkAllId,
// ['indeterminate'+key]:!!checkedList.length && (checkedList.length < checkAll.length),
// ['plainOptions'+key]:plainOptions,
['checkedList'+key]:checkedList,
['allListId'+key]:allListId
};
newList.push(obj)
});
yield put({
type: 'updateState',
payload: {
authorityList: menuList,
newList: newList
}
});
}
} ,
定义一个CheckGroup.js的组件,并将此组件循环输出:
import React, { Component, PropTypes } from 'react';
import { Checkbox } from 'antd';
import { connect } from 'dva';
import styles from './CharacterContent.less';
const CheckboxGroup = Checkbox.Group;
const CheckGroup=({checkId,checkAll,checkedList,checkAllValue,checkAllLable,hasChildren,children,dispatch,character,allListId,indeterminate,checkAllId})=>{
function onCheckAllChange(e){
let newList=character.newList;
newList[checkId]={
['allListId'+checkId]:allListId,
['checkAllId'+checkId]:checkAllId,
['checkedList'+checkId]: e.target.checked ? allListId : [],
// ['indeterminate'+checkId]: !indeterminate,
['checkAll'+checkId]: e.target.checked,
};
dispatch({
type:'character/updateState',
payload:{
newList:newList
}
})
}
function selectCheckbox(checkedList){
let newList=character.newList;
newList[checkId]={
['allListId'+checkId]:allListId,
['checkAllId'+checkId]:checkAllId,
['checkedList'+checkId]: checkedList,
// ['indeterminate'+checkId]: !!checkedList.length && (checkedList.length < allListId.length),
['checkAll'+checkId]: checkedList.length >0,
};
dispatch({
type:'character/updateState',
payload:{
newList:newList
}
})
}
return(
<div className={styles.allCheckbox} id={checkId}>
<Checkbox checked={checkAll } value={checkAllValue} onChange={(e)=>onCheckAllChange(e)} >{ checkAllLable}</Checkbox >
{
hasChildren ?
<CheckboxGroup className={styles.subCheckbox} value={checkedList} onChange={selectCheckbox}>
{
children.map((sub, subKey) => {
return <Checkbox value={sub.menuid} id={`${sub.menuid}`} key={subKey} >{sub.name}</Checkbox >
})
}
</CheckboxGroup > : null
}
</div >
)
}
CheckGroup.propTypes = {
// searchValue: PropTypes.string,
// characterList: PropTypes.array,
// dispatch: PropTypes.func,
// showSubModal: PropTypes.bool,
// deteleSubModal: PropTypes.bool
};
export default connect(({ character, loading }) => ({ character, loading }))(CheckGroup);
然后引用这个组件
import CheckGroup from ‘./CheckGroup’
并将代码改为:
{
authorityList.map((item,key) => {
return (
<CheckGroup key={key} checkId={key} checkAll={newList[key]['checkAll'+key]} checkAllId={newList[key]['checkAllId'+key]} allListId={newList[key]['allListId'+key]} checkedList={newList[key]['checkedList'+key]} checkAllValue={item.menuid} checkAllLable={item.name} hasChildren={item.hasChildren} children={item.children} onChangeGroup={this.selectCheckbox}/>
)
})
}
终于实现了这个功能,不过感觉应该还有其他的方法,欢迎大家提出~