使用 javascript 添加或删除嵌套 JSON 对象中的特定节点
Add or Delete particular node in nested JSON Object using javascript
我想制作树状结构。在每个节点中有两个符号(+ 添加一个节点和 - 删除特定节点)。我面临的问题是如何从嵌套 json 添加/删除节点(子节点)。对于一层或两层嵌套没问题,但对于不止一层,我无法编写一些通用代码来执行此操作。下面是默认的 json 和我必须对其进行 add/delete 操作的树的图片。在 HTML 和 CSS 中,我没有 problem.Some 引导或提示是受欢迎的,因为最近 2 天我正在处理这个问题。谢谢
JSON :
{
"name": "abc",
"children": [{
"name": "def",
"children": [{
"name": "jkl",
"children": [{
"name": "vwxyz",
"children": []
}]
}]
},
{
"level": "2",
"name": "ghi",
"children": [{
"name": "mno",
"children": []
}, {
"name": "pqr",
"children": [{
"name": "stu",
"children": []
}]
}]
}
]
}
由于您有唯一的名称,您可以创建一个查找对象,其中名称属性作为键,树节点作为其值。然后,您可以根据名称快速进入任何节点。通过向每个节点对象添加父节点 属性,您可以找到给定节点的父节点。
var data = { name: "abc", ... };
var lookup = {};
function buildLookup(node, parent) {
node.parent = parent;
lookup[node.name] = node;
if (node.children) {
for (var i = 0; i < node.children.length; i++) {
buildLookup(node.children[i], node);
}
}
}
buildLookup(data, null);
// lookup object now populated
您的 -/+ 按钮可以合并名称属性以传递给事件处理程序:
<button class="button-plus" data-name="def">+</button>
<button class="button-minus" data-name="def">-</button>
处理程序:
var addBtns = document.querySelectorAll(".button-plus");
for (var i=0; i < addBtns.length; i++) {
addBtns[i].addEventListener("click", function (e) {
var node = lookup[this.dataset.name];
// create a new empty child
var child = {
name: "new child",
parent: node,
children: []
};
// add it to the children array
node.children.push(child);
// add it to the lookup
lookup[child.name] = child;
});
}
一种方法是使用节点数据结构而不是 JSON。需要时,可以轻松地将普通 JS 对象与 JSON 相互转换。
这样处理数据就简单多了。
您可以将 DOM 事件连接到节点上的方法,并在完成后转换为 JSON
function Node(value, parent) {
let children = [];
let self = {
value: value,
children: children,
// create and return a new node for the value
add: value => {
let child = Node(value, self);
children.push(child);
return child;
},
// remove this node from its parent, if it has one
remove: () => {
if (parent !== null && typeof parent !== 'undefined') {
let indexInParent = parent.children.indexOf(self);
if (indexInParent > -1) {
parent.children.splice(indexInParent, 1);
}
}
},
// return a plain object that has only data and contains no references to parents
// JSON.stringify cannot handle circular references
dataOnly: function () {
return {
value: value,
children: children.map(c => c.dataOnly())
}
},
// return a JSON string for this object
makeJSON: () => JSON.stringify(self.dataOnly())
};
return self;
}
root = Node('lame');
child = root.add('child');
console.log(root.makeJSON());
// logs {"value":"lame","children":[{"value":"child","children":[]}]}
我想制作树状结构。在每个节点中有两个符号(+ 添加一个节点和 - 删除特定节点)。我面临的问题是如何从嵌套 json 添加/删除节点(子节点)。对于一层或两层嵌套没问题,但对于不止一层,我无法编写一些通用代码来执行此操作。下面是默认的 json 和我必须对其进行 add/delete 操作的树的图片。在 HTML 和 CSS 中,我没有 problem.Some 引导或提示是受欢迎的,因为最近 2 天我正在处理这个问题。谢谢
JSON :
{
"name": "abc",
"children": [{
"name": "def",
"children": [{
"name": "jkl",
"children": [{
"name": "vwxyz",
"children": []
}]
}]
},
{
"level": "2",
"name": "ghi",
"children": [{
"name": "mno",
"children": []
}, {
"name": "pqr",
"children": [{
"name": "stu",
"children": []
}]
}]
}
]
}
由于您有唯一的名称,您可以创建一个查找对象,其中名称属性作为键,树节点作为其值。然后,您可以根据名称快速进入任何节点。通过向每个节点对象添加父节点 属性,您可以找到给定节点的父节点。
var data = { name: "abc", ... };
var lookup = {};
function buildLookup(node, parent) {
node.parent = parent;
lookup[node.name] = node;
if (node.children) {
for (var i = 0; i < node.children.length; i++) {
buildLookup(node.children[i], node);
}
}
}
buildLookup(data, null);
// lookup object now populated
您的 -/+ 按钮可以合并名称属性以传递给事件处理程序:
<button class="button-plus" data-name="def">+</button>
<button class="button-minus" data-name="def">-</button>
处理程序:
var addBtns = document.querySelectorAll(".button-plus");
for (var i=0; i < addBtns.length; i++) {
addBtns[i].addEventListener("click", function (e) {
var node = lookup[this.dataset.name];
// create a new empty child
var child = {
name: "new child",
parent: node,
children: []
};
// add it to the children array
node.children.push(child);
// add it to the lookup
lookup[child.name] = child;
});
}
一种方法是使用节点数据结构而不是 JSON。需要时,可以轻松地将普通 JS 对象与 JSON 相互转换。
这样处理数据就简单多了。 您可以将 DOM 事件连接到节点上的方法,并在完成后转换为 JSON
function Node(value, parent) {
let children = [];
let self = {
value: value,
children: children,
// create and return a new node for the value
add: value => {
let child = Node(value, self);
children.push(child);
return child;
},
// remove this node from its parent, if it has one
remove: () => {
if (parent !== null && typeof parent !== 'undefined') {
let indexInParent = parent.children.indexOf(self);
if (indexInParent > -1) {
parent.children.splice(indexInParent, 1);
}
}
},
// return a plain object that has only data and contains no references to parents
// JSON.stringify cannot handle circular references
dataOnly: function () {
return {
value: value,
children: children.map(c => c.dataOnly())
}
},
// return a JSON string for this object
makeJSON: () => JSON.stringify(self.dataOnly())
};
return self;
}
root = Node('lame');
child = root.add('child');
console.log(root.makeJSON());
// logs {"value":"lame","children":[{"value":"child","children":[]}]}