根据我的真实项目使用此测试代码:
var test = ko.mapping.fromJS({ id: 1, kids: [{ name: "sue"}] });
test.kids.push({ name: "tim" });
test.kids.push(ko.mapping.fromJS({ name: "joe" }));
console.log(test);
console.log(test.kids()[0]);
console.log(test.kids()[1]);
console.log(test.kids()[2]);
test.kids()[2].__ko_mapping__ = undefined;
console.log(test.kids()[2]);
Firebug中的控制台输出显示:
Object { __ko-mapping__={...}, id=d(), kids=d() }
Object { name=d() }
Object { name="tim" }
Object { __ko-mapping__={...}, name=d() }
Object { name=d() }
我的目标是在初始数据映射后将项添加到kids
数组,并使这些项看起来与添加的原始项相同。如果我只是直接在数组上推送一个对象,那么这些属性就不是可观察的。如果我使用ko.mapping.fromJS
推送对象,则会包含额外的__ko_mapping__
对象。我宁愿没有额外的对象,因为它似乎不需要(原始项目没有它并且工作正常),并且我可能在我稍后添加1000个项目的地方使用相同的设计。
将对象设置为undefined
似乎确实删除了额外的对象,但如果可能的话,最好不要在第一时间创建它。
答案 0 :(得分:1)
基于缺乏任何其他答案,唯一的答案是可能是更好的设计实践,但实际上与我要求的相反(它为每个孩子添加了一个映射对象)..我猜我已经我原来的问题得到了答案,只是假设必须有更好的方法。
因此,对于未来的读者,这里是:
test.kids()[2].__ko_mapping__ = undefined;
如果你想摆脱它,只需将 ko_mapping 设置为undefined。
请参阅评论和其他答案,了解为什么这不是一般的好主意。对于我的需求,也许你有同样的想法,这是一个好主意。
答案 1 :(得分:0)
我通常发现为'Kids'创建一个强大的原型很有用,并告诉映射插件在映射初始数据时使用它。这将导致数组的内容相同,并且具有允许每个Kid的计算和可观察量的额外好处。
var Kid = function(json){
ko.mapping.fromJS(json, {}, this);
}
var mapping = {
'kids': {
create: function(options) {
return new Kid(options.data);
}
}
}
现在,如果你必须添加项目,只需创建新的孩子。
var test = ko.mapping.fromJS({ id: 1, kids: [{ name: "sue"}] }, mapping);
test.kids.push(new Kid({ name: "tim" }));
test.kids.push(new Kid({ name: "joe" }));
console.log(test);
console.log(test.kids()[0]);
console.log(test.kids()[1]);
console.log(test.kids()[2]);
然后,Firebug显示:
Object {id: function, kids: function, __ko_mapping__: Object}
Kid {name: function, __ko_mapping__: Object}
Kid {name: function, __ko_mapping__: Object}
Kid {name: function, __ko_mapping__: Object}
答案 2 :(得分:0)
http://knockoutjs.com/documentation/plugins-mapping.html
您可以选择要映射的属性以及方式。