我想知道在JavaScript中更新多级对象集合成员的最佳方法是什么
以下是我的收藏的简化版本:
this.Steps = [
{ id: 1, text: "test", childSteps:
[
{ id: 2, text: "test"},
{ id: 3, text: "test"},
{ id: 4, text: "test", childSteps:
[
{ id: 10, text: "test"},
{ id: 11, text: "test"}
]}
},
{ id: 5, text: "test"},
{ id: 6, text: "test"},
{ id: 7, text: "test"},
{ id: 8, text: "test"},
{ id: 9, text: "test"}
]
}
];理想的情况是有一个如下所示的函数:
updateObjectByID(11, 'string to be set');当我们只有一个级别的对象时,这很容易做到。但是,当在多级集合上使用递归时,它变得更加困难。
我目前正在使用一个解析整个集合并构建字符串的函数,如下所示:
this.Steps[0].childSteps[3].childSteps[1].text == "string to be set"然后我在这个字符串上做eval()。
我相信可能会有一个更干净的解决方案。
使用eval使得我的类不可能压缩btw。
任何帮助都将不胜感激。
提前感谢
发布于 2013-02-08 00:41:47
您可以通过id构建对象映射,以便直接访问:
var map = {};
(function recurse(steps) {
for (var i=0; i<steps.length; i++) {
var step = steps[i];
map[ step.id ] = step;
if ("childSteps" in step)
recurse(step.childSteps);
}
})(this.Steps);
function updateObjectByID(id, string) {
map[id].text = string;
}关于你的代码的评论:你过度复杂化了。当满足条件if(obj.id == objId)时,您已经拥有了您的obj引用!现在绝对不需要搜索到它的路径,从它构建一个字符串,并对其求值。直接赋值给它的属性!
function(steps, objId, value, whatParam, command) {
if (typeof whatParam == 'undefined')
whatParam = 'selected';
$.each(steps, function(index, obj){
if(obj.id == objId) {
// removed a lot of unecessary stuff
// not sure, looks like "value" was evaled sometimes as well
obj[whatParam] = value;
} // insert an "else" here if ids are unique
if (typeof obj.childSteps != 'undefined') {
this.setupObjectState(obj.childSteps, objId, value, whatParam, command);
}
});
}发布于 2013-02-08 00:43:09
由于您使用ID调用updateObjectById(),因此ID必须是唯一的。你为什么不像这样改变你的结构:
this.Steps = [
{ id: 1, text: "test" },
{ id: 2, parent: 1, text: "test" },
{ id: 3, parent: 1, text: "test" },
{ id: 4, parent: 1, text: "test" },
{ id: 10, parent: 4, text: "test" },
{ id: 11, parent: 4, text: "test" },
{ id: 5, parent: 1, text: "test"},
{ id: 6, parent: 1, text: "test"},
{ id: 7, parent: 1, text: "test"},
{ id: 8, parent: 1, text: "test"},
{ id: 9, parent: 1, text: "test"}
]这样,您就可以轻松地更新条目,如下所示:
function updateObjectByID(id, text) {
for(var i = 0; i < this.Steps.length; i++) {
if(this.Steps[i].id === id) {
this.Steps[i].text = text;
break;
}
}
}使用额外的属性parent,您仍然可以轻松地获取元素的所有子元素,如下所示:
function getChildrenByID(id) {
var array = [];
for(var i = 0; i < this.Steps.length; i++) {
if(this.Steps[i].parent === id) {
array.push(this.Steps[i]);
}
}
return array;
}发布于 2013-02-08 00:43:35
你必须递归地向下移动你的树形结构,用目标"id“搜索对象,并替换它的文本。例如:
function updateObjectByID(obj, id, text) {
if (!obj) return;
if (obj.id === id) {
obj.text = text;
} else if ((typeof(obj)==='object') && (obj.constructor===Array)) {
for (var i=0; i<obj.length; i++) {
updateObjectByID(obj[i], id, text);
}
} else if (obj.childSteps) {
updateObjectByID(obj.childSteps, id, text);
}
}
updateObjectByID(this.Steps, 11, 'String to be set');但是,此解决方案可以通过修剪树进行优化。
https://stackoverflow.com/questions/14755823
复制相似问题