【发布时间】:2013-04-16 16:34:03
【问题描述】:
使用这个测试代码,基于我的真实项目:
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 似乎确实删除了额外的对象,但如果可能的话,宁愿不首先创建它。
【问题讨论】:
-
__ko_mapping__在调用ko.mapping.fromJS时由“根”元素上的映射插件创建和使用。你不应该关心它,它是不可配置的,它是自动添加的。如果您担心内存问题,那么您应该为您的项目创建一个构造函数并使用它而不是映射插件。 -
我同意上面的评论。 ko_mapping 用于淘汰赛以跟踪添加的内容。当你调用 ko.mapping.toJS() 函数时,那些额外的属性将被删除,当你想将它传递回服务器时,你应该调用它来获取一个干净的对象。另一方面,如果您正在迭代对象的属性并且您担心这可能会导致问题,那么您应该迭代并检查 hasOwnProperty 以确保您正在迭代对象自己的属性。 ko_mapping 将不在其中。
-
我猜是这样,但似乎很常见,他们会为此提供更优化的方法。我只是在映射一个非常基本的对象,然后想在以后添加一些东西......很遗憾我不得不脱离映射库来做到这一点,或者只是“不用担心”额外的内存(可能是大小的 5 倍)。
-
如果映射信息一直存在于项目上,我更有可能将其视为“必需”,但对于在初始期间被映射为子项的项目则不存在映射。我想我可以在源代码中找到一个库函数,该函数在每个子节点上被调用以进行初始映射,并直接调用它......但这不是一个好主意。
标签: knockout.js knockout-mapping-plugin