2

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

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确实似乎删除了额外的对象,但如果可能的话,宁愿不首先创建它。

4

3 回答 3

1

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

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

test.kids()[2].__ko_mapping__ = undefined;

如果您想摆脱它,只需将ko_mapping设置为未定义。

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

于 2013-05-02T22:57:39.413 回答
0

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

http://jsfiddle.net/Z9GF5/

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}
于 2013-04-30T13:58:22.387 回答
0

http://knockoutjs.com/documentation/plugins-mapping.html

您可以选择映射哪些属性以及如何映射。

于 2014-06-10T19:05:20.893 回答