开发各种功能具体实现

本例为各种功能的具体实现

  • (1)实现table里面的那个,点击左边的加号,展开子菜单。遍历拼接dataSource。这个是所有数据直接返回
    • 这里面用了两个递归。具体思路就是:有一个存放所有数据的数组dataArr;数组里面的数据如果插入到了dataSource里面,就把这一条从dataArr里面删除,直到dataArr为空,就遍历完了
this.renderDataSource(dataArr); // dataArr为后台返回的数据
    renderDataSource(dataArr: any) { // 用后台返回回来的数组来构建table的dataSource,数据里面的key,就是task_id
        let dataSource = [], // dataSource就是已经构建了的节点数据
            spliceDataIndex = []; // 在数据数组里面找到的数据的index
        // 下面是渲染第一层的数据,先把p_task_id为0的数据渲染出来,然后再把后面的慢慢加上去
        dataArr.forEach((value, index, arr) => {
            let { task_id, p_task_id, task_name, task_type, task_sort, task_status } = value,
                key = value.task_id;
            if (p_task_id === 0) {
                dataSource.push({ key, task_id, p_task_id, task_name, task_type, task_sort, task_status });
                spliceDataIndex.push(index);
            }
        });
        // 由于spliceDataIndex数组的index是从小到大的,所以如果从小到大删除dataArr中的项,那么就会乱;所以就转一个方向,从大到小来删
        spliceDataIndex.reverse().forEach((value,index,arr) => {
            dataArr.splice(value,1);
        });
        
        this.renderChildDataSource(dataArr, dataSource);
        console.log('最后的',dataSource,spliceDataIndex.reverse(),dataArr);
        return dataSource;
    }
    renderChildDataSource(dataArr: any, dataSource: any) { // 这个是渲染除去第一层之外的,子节点的数据
        let spliceDataIndex = [];
        dataArr.forEach((childValue, index, arr) => {
            let { task_id, p_task_id, task_name, task_type, task_sort, task_status } = childValue,
                key = task_id,
                isFind = false;
            isFind = this.findParentNodePostion({ key,task_id, p_task_id, task_name, task_type, task_sort, task_status },dataSource);
            if (isFind) spliceDataIndex.push(index);
        });

        spliceDataIndex.reverse().forEach((value,index,arr) => {
            dataArr.splice(value,1);
        });

        if (dataArr.length !== 0) { // 如果之前还没有把dataArr遍历完,就需要再进行遍历
            this.renderChildDataSource(dataArr,dataSource);
        } else {
            Message.success('成功渲染所有元素',1);
        }
        console.log('剩下的元素数量',dataArr);
    }
    // 遍历已经生成的节点树,找到p_task_id对应的父task_id位置,然后把value插入进去
    findParentNodePostion(childValue:any,dataSource:any) {
        let {p_task_id} = childValue,
            isFind = false; // 判断是否找到了位置
        dataSource.find((fatherValue, index, arr) => {
            if (p_task_id === fatherValue.task_id) { // 直接找到位置
                if (fatherValue.children) { // 如果父节点上面children属性存在,就直接push进去,不存在就自己加一个children属性
                    fatherValue.children.push(childValue);
                } else {
                    fatherValue.children = [childValue];
                }
                isFind = true;
                return true;
            } else {
                if (fatherValue.children) { // 当前节点没找到,但是当前有子节点。就拿子节点这个数组来再次遍历
                    isFind = this.findParentNodePostion(childValue,fatherValue.children);
                    if(isFind) return true;
                }
            }
        });
        return isFind;
    }
  • (2)实现table里面的那个,点击左边的加号,展开子菜单。遍历拼接dataSource。这个是第一次只返回第一层,然后点击加号发送请求返回第二层
    // 遍历已经生成的节点树,返回找到的父节点位置的value值
    findParentNodePostion(p_task_id: any, dataSource: any) {
        let returnFatherValue = [];
        dataSource.find((fatherValue, index, arr) => {
            if (p_task_id === fatherValue.task_id) { // 直接找到位置
                returnFatherValue = fatherValue;
                return true;
            }
            console.log('看看这里的fatherValue.children',fatherValue);
            if (fatherValue.children && fatherValue.children.length !== 0) { // 当前节点没找到,但是当前有子节点。就拿子节点这个数组来再次遍历
                returnFatherValue = this.findParentNodePostion(p_task_id, fatherValue.children);
                if (returnFatherValue.length !== 0) return true;
            }
        });
        console.log('最后找到的returnFatherValue', returnFatherValue);
        return returnFatherValue;
    }

    renderFatherDataSource(dataArr: any) { // 用后台返回回来的数组来构建table的dataSource,数据里面的key,就是task_id
        let dataSource = []; // dataSource就是已经构建了的节点数据
        // 下面是渲染第一层的数据,先把p_task_id为0的数据渲染出来,然后再把后面的慢慢加上去
        dataArr.forEach((value, index, arr) => {
            let { task_id, p_task_id, task_name, task_type, task_sort, task_status, create_time } = value;
            let key = value.task_id;
            let children = []; // 这个为给每一个行数据前面都添加一个+号
            let p_task_name = '顶层任务'; // 这里是加了一个p_task_name的,因为在新增和修改的时候,拿到行数据进入pop,都是需要p_task_name的,但是原数据只有p_task_id;所以这里直接加一个
            if (p_task_id === 0) {
                dataSource.push({ key, task_id, p_task_id, p_task_name, task_name, task_type, task_sort, task_status, create_time, children });
                // spliceDataIndex.push(index);
            }
        });
        console.log('最后渲染成功的dataSource是', dataSource, this, dataArr);
        return dataSource;
    }

    // 这个是渲染除去第一层之外的,子节点的数据;empty_p_task_id为空节点的父元素。而且由于这个dataSource是深复制的this.state.dataSource,所以下面代码可以修改这个dataSource,然后返回回去就好了
    renderChildDataSource(dataArr: any, dataSource: any, empty_p_task_id: any = false) {
        // 判断,当empty_p_task_id存在的时候,直接把dataSource上面的children属性删除
        console.log('进入renderChild之后,看看传入这里的值啊', dataArr, dataSource, empty_p_task_id);
        if (empty_p_task_id !== false) {
            let fatherValue = this.findParentNodePostion(empty_p_task_id, dataSource);
            delete fatherValue.children;
            console.log('进入这里之后,这里的datasource', dataSource);
            return dataSource;
        }

        dataArr.forEach((childValue, index, arr) => {
            let { task_id, p_task_id } = childValue;
            let fatherValue = this.findParentNodePostion(p_task_id, dataSource);
            childValue.key = task_id;
            childValue.children = [];
            console.log('看看这里的childValue',childValue);
            fatherValue.children.push(childValue);
        });

        return dataSource;
    }

おすすめ

転載: blog.csdn.net/rocktanga/article/details/121348755