我有以下对象
var json = {
items:[
{id:45 , lable:"Test 1.2.1", parent_id: 2},
{id:12, lable:"Test 1.0", parent_id: 0},
{id:32, lable:"Test 1.1", parent_id: 12},
{id:2, lable:"Test 1.2", parent_id: 12}
]
}
使用此对象我需要创建一个嵌套列表,它在浏览器中将如下所示
我的方法是编写一个能够遍历对象并将值存储在元素列表数组中的函数
function appendItems(json){
var list = json.items;
var listelem = [];
list.forEach(function(i){
var listelements = document.createElement('li');
listelements.setAttribute("id",i.id);
listelements.setAttribute("data-parent-id", i.parent_id);
listelements.innerText = i.lable;
listelem.push(listelements);
})
console.log(listelem);
}
但我不确定如何从这一点获得嵌套结构
答案 0 :(得分:4)
我首先将您的数组转换为实际的树。你可以这样做:
var obj = {
items:[
{id:45 , lable:"Test 1.2.1", parent_id: 2},
{id:12, lable:"Test 1.0", parent_id: 0},
{id:32, lable:"Test 1.1", parent_id: 12},
{id:2, lable:"Test 1.2", parent_id: 12}
]
}
// first we create a dictionary so we can find elements by id easily
var objDict = obj.items.reduce(function(p,c) {
p[c.id] = c;
c.children = [];
return p;
}, {});
// then we build our tree
var tree = obj.items.reduce(function(p,c) {
// if the parent_id is zero, we have found the root.
if (!c.parent_id) {
p = c;
}
// otherwise, figure out who the parent is and add this one as a child
else {
objDict[c.parent_id].children.push(c);
}
return p;
}, {});
console.log(JSON.stringify(tree));

这会给你一个如下所示的对象:
{
"id": 12,
"lable": "Test 1.0",
"parent_id": 0,
"children": [
{
"id": 32,
"lable": "Test 1.1",
"parent_id": 12,
"children": []
},
{
"id": 2,
"lable": "Test 1.2",
"parent_id": 12,
"children": [
{
"id": 45,
"lable": "Test 1.2.1",
"parent_id": 2,
"children": []
}
]
}
]
}
现在应该可以轻松处理。从根开始并创建一个节点,然后根据需要对每个生成嵌套节点的子进行深度优先搜索。
这样的事情:
processTree(tree, document.getElementById("list"));
function processTree(node, element) {
var li = document.createElement('li');
li.innerText = node.lable;
element.appendChild(li);
if (node.children.length) {
var ul = document.createElement('ul');
li.appendChild(ul);
// note: you might want / need to actual sort the children first
// but it's not clear from the OP if sorting by id will always give the right order
for (var i=0; i < node.children.length; i++) {
processTree(node.children[i], ul);
}
}
}
为您提供一个这样的工作示例:
var obj = {
items: [{
id: 45,
lable: "Test 1.2.1",
parent_id: 2
}, {
id: 12,
lable: "Test 1.0",
parent_id: 0
}, {
id: 32,
lable: "Test 1.1",
parent_id: 12
}, {
id: 2,
lable: "Test 1.2",
parent_id: 12
}]
}
var objDict = obj.items.reduce(function(p, c) {
p[c.id] = c;
c.children = [];
return p;
}, {});
var tree = obj.items.reduce(function(p, c) {
if (!c.parent_id) {
p = c;
} else {
objDict[c.parent_id].children.push(c);
}
return p;
}, {});
processTree(tree, document.getElementById("list"));
function processTree(node, element) {
var li = document.createElement('li');
li.innerText = node.lable;
element.appendChild(li);
if (node.children.length) {
var ul = document.createElement('ul');
li.appendChild(ul);
for (var i = 0; i < node.children.length; i++) {
processTree(node.children[i], ul);
}
}
}
&#13;
<ul id="list">
</ul>
&#13;
答案 1 :(得分:0)
这是一个使用递归的简单解决方案。我使用了一个辅助函数,它返回给定parent_id的子数组。我希望你觉得它很有帮助。
'use strict';
(function() {
function childrenOf(targetId, items) {
var children = [];
items.forEach(function(item) {
if (item.parent_id === targetId) {
children.push(item);
}
});
return children;
}
function nestedList(id, items) {
var result = '';
var children = childrenOf(id, items);
if (children.length) {
result = '<ul>';
children.forEach(function(child) {
result += '<li>';
result += child.label;
result += nestedList(child.id,items);
result += '</li>';
});
result += '</ul>';
}
return result;
}
var json = {
items:[
{id:45 , label:"Test 1.2.1", parent_id: 2},
{id:12, label:"Test 1.0", parent_id: 0},
{id:32, label:"Test 1.1", parent_id: 12},
{id:2, label:"Test 1.2", parent_id: 12}
]
}
var rootId = 0;
var output = nestedList(rootId, json.items);
console.log('<html><body>');
console.log(output);
console.log('</body></html>');
})();
它产生以下输出:
<html>
<body>
<ul>
<li>Test 1.0
<ul>
<li>Test 1.1</li>
<li>Test 1.2
<ul>
<li>Test 1.2.1</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>