Knockout.js knockoutjs-mapping,将新项添加到子数组中,而不使用额外的mapping对象

Knockout.js knockoutjs-mapping,将新项添加到子数组中,而不使用额外的mapping对象,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,基于我的真实项目,使用此测试代码: 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]); conso

基于我的真实项目,使用此测试代码:

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
推送对象,它们会得到一个额外的
\uuuuuu ko\u mapping\uuuu
对象。我不希望有额外的对象,因为它似乎不需要(原始项目没有它,工作正常),我可能会在以后添加1000个项目的地方使用相同的设计


将对象设置为“未定义”似乎确实会删除额外的对象,但如果可能的话,我宁愿一开始就不创建它。

我通常认为为“孩子”创建一个强大的原型并告诉映射插件在映射初始数据时使用它很有用。这将导致数组的内容完全相同,并具有允许每个孩子进行计算和观察的额外好处

现在,如果你必须添加项目,只需创建新的孩子

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}

基于缺乏任何其他答案,唯一的答案可能是更好的设计实践,但实际上与我要求的相反(它为每个孩子添加了一个映射对象)。。我想我在最初的问题中已经找到了答案,只是假设一定有更好的方法

因此,对于未来的读者,这里是:

test.kids()[2].__ko_mapping__ = undefined;
如果您想摆脱它,只需将ko_mapping设置为未定义即可

请参阅评论和其他答案,了解为什么这通常不是一个好主意。为了满足我的需求,也许你也有同样的需求,这是个好主意。


您可以选择映射哪些属性以及映射方式。

调用
ko.mapping.fromJS
时,“root”元素上的映射插件将创建并使用
ko.mapping。你不应该关心它,它是不可配置的,它是自动添加的。如果您担心内存问题,那么您应该为您的项创建一个构造函数,并使用它来代替映射插件。我同意上面的评论。ko_映射用于敲除以跟踪添加的内容。当您调用ko.mapping.toJS()函数时,这些额外的属性将被删除,当您想要将对象传递回服务器时,应该调用这些属性来获取干净的对象。另一方面,如果您正在迭代对象的属性,并且担心这可能会导致问题,那么您应该迭代并检查hasOwnProperty,以确保您正在迭代对象自己的属性。ko_映射将不会出现在这一点上。我想是的,但似乎是一件非常常见的事情,他们会有一个更优化的方法来实现这一点。我只是映射了一个非常基本的对象,然后想在以后添加一些东西。。。遗憾的是,为了实现这一点,我不得不脱离映射库,或者只是“不担心”额外的内存(可能是大小的5倍)。如果映射信息一直存在于项目上,我更可能接受它为“必需”,但对于在初始映射期间映射为子项的项目,它并不存在。我想我可能在源代码中找到一个库函数,在初始映射的每个子级上调用它,并直接调用它。。。但这不是一个好主意。请在答案中包含相关部分,而不仅仅是链接到外部来源。
test.kids()[2].__ko_mapping__ = undefined;