antd table 权限树操作

2 篇文章 0 订阅
1 篇文章 0 订阅

废话不多说,我的需求:

  1. 节点选中后,其父节点也自动选中
  2. 节点取消后,其子节点也自动取消

场景:
在资源权限树中,我们如果使用下级权限的前提是拥有上级权限,即若无上级权限,也不会有下级权限

在这里插入图片描述

问题:
在使用 Antd Table 组件中 Checkbox 时,操作结果是:
选择节点时,其子结点自动选择中;
当某结点下的所有结点选中中此结点自动选中

预置的功能与我们的想要的效果不一样;所以我们必须自己来控制选中的效果

核心代码:

expandable:{
 expandedRowKeys,
},
rowSelection:{
  selectedRowKeys,
  onSelect:(record, selected, selectedRows, nativeEvent)=>{
    const rowKeys = [...selectedRowKeys];
    if(selected) {
      // 选择
      const arr = treeUtil.findParentInTree(dataSource, item=>item.id===record.id).map(item=>item.id);
      setSelectedRowKeys(Array.from(new Set([...rowKeys, ...arr])))
    } else {
      // 取消
      const arr = treeUtil.findChildrenInTree(dataSource, item=>item.id===record.id).map(item=>item.id);
      setSelectedRowKeys(rowKeys.filter(item=>arr.indexOf(item)===-1))
    }
  }
},

treeUtil


//遍历每个节点
export function mapTree(treeData= [], callback = ()=>{}, childrenName='children') {

  function runTree(arr){

    for (let ind = 0, len = arr.length; ind < len; ind++) {
      const item = arr[ind];
      
      callback(item)

      runTree(item[childrenName]||[])
    }
  }


  return runTree(treeData)
}


// 把树形结构扁平化
export function flatTree(treeData= [], callback = ()=>{}, childrenName='children') {// treeData 为数组
  function runTree(arr, parent=null){
    const ret = [];
    for (let ind = 0, len = arr.length; ind < len; ind++) {
      const item = arr[ind];
      
      if(parent!==null) {
        
        callback(item, parent);
      }
      // 
      ret.push(item);
      ret.push(...runTree(item[childrenName]||[], item))
      // delete item[childrenName]
      
    }

    return ret;
  }


  return runTree(treeData)
}

// 把扁平化的数据造成树
export function buildTree(flatData= [], config={
  id: 'id',
  parendId: 'parent_id',
  rootId: 0,// 0 false  undefined null
}){

  const obj = {};
  for (let ind = 0, len = flatData.length; ind < len; ind++) {
    const item = flatData[ind];
    obj[item[config.id]] = item;
  }
  // 完成列举

  for (let ind = 0, len = flatData.length; ind < len; ind++) {
    const item = flatData[ind];
    const pId = item[config.parendId];
    if(pId!==config.rootId && obj[pId]) { //
      obj[pId].children=obj[pId].children||[];
      obj[pId].children.push(item);
    }
  }

  for (let ind = 0, len = flatData.length; ind < len; ind++) {
    const item = flatData[ind];
    const pId = item[config.parendId];
    if(pId!==config.rootId){
      delete obj[item[config.id]]
    }
  }

  return Object.values(obj);
}

// 标准化树型结构
export function reMapTree(treeData= [], callback=()=>{}, childrenName='children', nChildrenName='children'){
  
  function runTree(arr){
    const ret = [];
    for (let ind = 0, len = arr.length; ind < len; ind++) {
      const item = arr[ind];
      const children = item[childrenName]||[];
      const nItem = callback(item)
      ret.push(nItem)
      if(children.length>0) {
        nItem[nChildrenName]=runTree(children);
      }
    }

    return ret;
  }

  const data = [...treeData]
  return runTree(data);
}

// 找某个符合条件的节点
export function findOneInTree(treeData= [], callback=()=>{}, childrenName='children') {
  let ret  = null;
  function runTree(arr) {

    for (let ind = 0, len = arr.length; ind < len; ind++) {
      const item = arr[ind];
      if(ret!==null) return true;
      if(callback(item)){
        ret = item;
        return true;
      } else {
        if(runTree(item[childrenName]||[])) {
          return true;
        }
        
      }
    }
  }

  runTree(treeData)
  return ret;
}


// 找某些符合条件的节点
export function findSomeInTree(treeData= [], callback=()=>{}, childrenName='children') {

  function runTree(arr){
    const ret = [];
    for (let ind = 0, len = arr.length; ind < len; ind++) {
      const item = arr[ind];
      
      if(callback(item)){
        ret.push(item)
      }

      ret.push(...runTree(item[childrenName]||[]))
    }

    return ret;
  }


  return runTree(treeData)
}

// 查找某个节点及其所有子节点
export function findChildrenInTree(treeData= [], callback=()=>{}, childrenName='children'){

  const node = findOneInTree(treeData, callback, childrenName)
  if(node) {
    return flatTree([node], ()=>{}, childrenName)
  }

  return [];
}

// 查找某个节点及其所有直系父节点
export function findParentInTree(treeData= [], callback=()=>{}, childrenName='children'){
  const ret  = [];
  function runTree(arr) {

    for (let ind = 0, len = arr.length; ind < len; ind++) {
      const item = arr[ind];
      if(callback(item)){
        ret.push(item)
        return true;
      } else {
        if(runTree(item[childrenName]||[])) {
          ret.push(item)
          return true;
        }
        
      }
    }
  }

  runTree(treeData)
  return ret;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值