antd Tree树形控件——不完全选中子节点后想要获取父节点的值,与后端交互

最近有一个权限树的需求,而且树的结构比较深,想要实现,在不完全选中子节点后能够获取父节点的值,一并传给后端。

不完全选中子节点后想要获取父节点的值

如图:选中【新增用户】和【批量导入】时,想要把【用户列表】和【用户管理】的id也传给后端。
在这里插入图片描述
通过阅读API文档
在这里插入图片描述
onCheck是复选框选中时触发,其中第二个参数是一个事件对象,他的返回值打印出来如下:
在这里插入图片描述
其中,有一个属性halfCheckedKeys就是关联父节点的值。这样,我们可以轻松的拿到值了,和选中节点拼接起来一起传给后台就好了。

onCheck = (checkedKeysValue, e) => {
    console.log('onCheck', checkedKeysValue);
    console.log('e.halfCheckedKeys :>> ', e);
    const checkedKeysResult = [...checkedKeysValue, ...e.halfCheckedKeys]
    this.setState({
        allCheckedId: checkedKeysResult
    })
};

解决反写的时候,如果传入父节点 key,则子节点自动选中的问题

上面的处理在新建的时候没有问题,一旦到了编辑或者查看的时候,需要反写权限树,就会出问题,因为我们是受控组件,用到了checkedKeys,选中复选框的树节点。请看API说明:
在这里插入图片描述
这样机会出现如果传入父节点 key,则子节点自动选中的情况。现在处理这个问题。

  • 首先,在渲染树结构时把所有的叶子节点存在一个数组,叫childArr
  • 接着,利用后端接口返回的id数组(有父节点,有叶子节点)与childArr数组比较,取出相同的元素(可考虑使用lodash的_.intersection方法
  • 最后,将获得的新数组给Tree组件的checkedKeys赋值

完整的权限树结构代码:

import React from 'react';
import { Tree } from 'antd';
let _ = require('lodash');

let childArr = []   // 存放所有子节点的数组

export default class CmpAuthTree extends React.Component {
    constructor(props) {
        super(props);
        this.getData(this.props.treeData)
        this.state = {
            autoExpandParent: true,
            expandedKeys: this.props.checkedList || [],
            allCheckedId: []   // 传给后台的id数组
        }
    }

    componentDidMount() {
        this.initData()
    }

    componentDidUpdate(prevProps) {
        this.updateData(prevProps)
    }

    initData = () => {
        let uniqueChild = this.dataClean(this.props.checkedList)
        this.setState({
            checkedKeys: uniqueChild || []
        })
    }

    updateData = (prevProps) => {
        let uniqueChild = this.dataClean(this.props.checkedList)
        if (prevProps.checkedList?.length !== this.props.checkedList?.length) {
            this.setState({
                expandedKeys: this.props.checkedList || [],
                checkedKeys: uniqueChild || []
            })
        }
    }

    getData = (data) => {
        data.map(res => {
            res.title = res.name
            res.key = res.menuId
            if (res.children && res.children.length > 0) {
                this.getData(res.children)
            } else {
                childArr.push(res.menuId)
            }
        })
        return childArr
    }

    dataClean = (checkedList) => {
        let allChildArr = this.getData(this.props.treeData)
        let uniqueChild = _.intersection(checkedList, allChildArr)
        return uniqueChild
    }

    onExpand = (expandedKeysValue) => {
        console.log('onExpand', expandedKeysValue);
        this.setState({
            autoExpandParent: false,
            expandedKeys: expandedKeysValue
        })
    };

    onCheck = (checkedKeysValue, e) => {
        console.log('onCheck', checkedKeysValue);
        console.log('e.halfCheckedKeys :>> ', e);
        const checkedKeysResult = [...checkedKeysValue, ...e.halfCheckedKeys]
        let uniqueChild = this.dataClean(checkedKeysResult)
        this.setState({
            allCheckedId: checkedKeysResult,
            checkedKeys: uniqueChild
        })
    };

    getCheckedList() {
        return this.state.allCheckedId
    }

    render() {
        return <Tree
            // defaultExpandAll
            disabled={this.props.readOnly}
            checkable
            selectable={false}
            onExpand={this.onExpand}
            expandedKeys={this.state.expandedKeys}
            autoExpandParent={this.state.autoExpandParent}
            onCheck={this.onCheck}
            checkedKeys={this.state.checkedKeys}
            treeData={this.props.treeData}
               />
    }
}

成功!

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值