JavaScript:通过ID设置嵌套对象值
JavaScript: Setting Nested object value by ID
我想知道在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"
然后我在那个字符串上执行CCD_ 1。
我相信可能有一个更清洁的解决方案。
使用eval使我的类无法压缩btw.
如有任何帮助,我们将不胜感激。
提前感谢
您可以通过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);
}
});
}
由于使用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;
}
您必须递归地降低树结构,搜索具有目标"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');
但是,此解决方案可以通过修剪树来进行优化。
function updateObjectByID(id, text) {
(function setText(steps) {
for(var i = 0; i < steps.length; i++){
var step = steps[i];
if(step.id === id){
step.text = text;
}
if ("childSteps" in step){
setText(step.childSteps);
}
}
})(this.Steps);
}
这是演示。http://jsfiddle.net/qDWX8/
相关文章:
- 如何使用javascript获取嵌套对象中所有子对象的单个属性
- 如何打印嵌套对象的所有值
- 设置嵌套对象属性的更好方法
- 嵌套对象结构
- 如何递归地获取嵌套对象中所有子对象的列表
- 更改嵌套对象的父子相关id
- 如何通过json对象数组为嵌套对象赋值
- Ember.js(2.5.0)如何设置嵌套对象值
- 嵌套对象文本访问父级
- 如何对两个嵌套对象进行排序
- 在javascript中使用方括号表示法的嵌套对象
- 具有嵌套对象数组的 Javascript 对象的递归搜索函数
- 更新嵌套对象的多个字段
- MongoDB嵌套对象数组后查询
- 在流星中插入嵌套对象
- 将嵌套对象数据添加到窗体中
- Chai深度包含了对嵌套对象的断言
- 使用Angular.js解析JSON中的嵌套对象数组
- 如何以编程方式添加到可变嵌套对象中
- Javascript嵌套对象访问根级别