我的需求是实现一个文件树,需要对原始数据结构进行处理,返回前端需要的数据。
1、mongodb
数据库中存放的原始数据:
let fData =
[
{
"pid": null,
"_id": "5e847c7f11228f1e88095dda",
"name": "公共资源"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e848a02b9d8b326ea4e2e0a",
"name": "文件夹一"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889473a9edb4235d98bae",
"name": "文件夹二"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"name": "文件夹三"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"name": "档案"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889663a9edb4235d98bb1",
"name": "音频"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e88896c3a9edb4235d98bb2",
"name": "项目部"
}
]
2、需要将其转化为层级数据。
const getTreeData = (nodes) => {
nodes.forEach((ele: any) => {
// 名称
ele.title = ele.name
ele.expand = true
ele.mode = 'show'
delete ele.name
let pid = ele.pid;
if (pid === null) {
// 是根元素的话 ,不做任何操作,如果是正常的for-i循环,可以直接continue.
} else {
// 如果ele是子元素的话 ,把ele扔到他的父亲的child数组中.
nodes.forEach(d => {
if (d._id == pid) {
let childArray = d.children;
if (!childArray) {
childArray = [];
}
childArray.push(ele);
d.children = childArray;
}
});
}
});
// 去除重复元素
return nodes.filter(ele => ele.pid === null);
}
const tData = getTreeData(fOnes);
执行完之后,tData
为:
[
{
"pid": null,
"_id": "5e847c7f11228f1e88095dda",
"title": "公共资源",
"expand": true,
"mode": "show",
"children": [
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e848a02b9d8b326ea4e2e0a",
"title": "文件夹一",
"expand": true,
"mode": "show"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889473a9edb4235d98bae",
"title": "文件夹二",
"expand": true,
"mode": "show"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"title": "文件夹三",
"expand": true,
"mode": "show",
"children": [
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"title": "档案",
"expand": true,
"mode": "show"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889663a9edb4235d98bb1",
"title": "音频",
"expand": true,
"mode": "show"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e88896c3a9edb4235d98bb2",
"title": "项目部",
"expand": true,
"mode": "show"
}
]
}
]
}
]
3、根据层级数据和一个子结点,获取父节点信息
const folder_id = '5e8889493a9edb4235d98baf';
// 定义数组,用于存放
let arr = [];
const getParentsIds = (data) => {
for (let i = 0; i < data.length; i++) {
let temp = data[i]
if (temp._id == folder_id) {
arr.push(temp._id);
return 1
}
if (temp && temp.children && temp.children.length > 0) {
let t = getParentsIds(temp.children)
if (t == 1) {
arr.push(temp._id)
return 1
}
}
}
}
getParentsIds(tData)
输出的arr
为
[ '5e8889493a9edb4235d98baf', '5e847c7f11228f1e88095dda' ]
4、根据原始数据和一个子结点,获取父节点信息
const fnode = {
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"title": "档案",
"expand": true,
"mode": "show"
};
const findP = (nodes, node) => {
const ans = [];
for (let i = 0; i < nodes.length; i++) {
if (node.pid == nodes[i]._id) {
ans.push(nodes[i]);
return ans.concat(findP(nodes, nodes[i]));
}
}
}
const pOnes = findP(fOnes, fnode).filter(x => {return x});
返回结果如下:
[
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"name": "文件夹三"
},
{
"pid": null,
"_id": "5e847c7f11228f1e88095dda",
"name": "公共资源"
}
]
5、根据原始数据和一个子结点,获取这个子结点下的子树
const fnode = {
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"title": "文件夹三"
};
//找子节点
const findC = (nodes, node) => {
let ans = [];
for (let i = 0; i < nodes.length; i++) {
if (node._id == nodes[i].pid) {
ans.push(nodes[i]);
ans = ans.concat(findC(nodes, nodes[i]));
}
}
return ans;
}
const cOnes = findC(fOnes, fnode);
此时cOnes
中数据为
[
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"name": "档案"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889663a9edb4235d98bb1",
"name": "音频"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e88896c3a9edb4235d98bb2",
"name": "项目部"
}
]