本例为各种功能的具体实现
- (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;
}