使用Knockout JS部分映射到现有对象

时间:2012-06-04 10:21:34

标签: javascript knockout.js knockout-mapping-plugin

我有一个复杂的模型,它包含一个ko.observable,ko.observableArray的加载和包含更多这些可观察对象的嵌套对象。

现在我最初必须在每个模型中创建方法,这些模型在组合构成较大的模型时采用Json数据然后填充其可观察量。现在我尝试了ko.mapping插件,但是当我使用它时:

ko.mapping.fromJS(jsonData, {}, existingModel);

这似乎适用于大多数对象,但我注意到,当我这样做时,它似乎完全覆盖了对象,因为我正在使用knockout js验证,即:

this.Name = ko.observable().extend({ required: true });
this.Age = ko.observable().extend({ required: true, digits: true });

问题是这些验证属性在使用映射模块时似乎被删除了,所以有没有办法让映射插件只更新值,而不是篡改对象模式......

如果有更好的方法将Json数据应用于模型,我非常乐意使用除ko.mapping之外的其他机制。

3 个答案:

答案 0 :(得分:2)

来自http://knockoutjs.com/documentation/plugins-mapping.html高级用法部分)

  

有时可能需要更多地控制映射的执行方式。这是使用映射选项完成的。它们可以在ko.mapping.fromJS调用期间指定。在后续调用中,您无需再次指定它们。

因此,例如,您可以尝试这样的事情:

var self = this;
var mapping = {
    update: function(arg) {
        var data = arg.data;

        return {
            Name: data.Name && self.Name(data.Name),
            Age: data.Age && self.Age(data.Age)
        }
    }
};
ko.mapping.fromJS(data, mapping);

答案 1 :(得分:2)

我最终不得不坚持使用我的方法,尽管我设法通过编写下面的简单插件来减少编写的大量代码来填充现有字段:

https://github.com/grofit/knockout.mapping.merge

这非常简单,并且除了将具有相同名称的对象与其现有字段匹配之外,实际上并没有做太多其他事情。我希望管理子对象创建,所以它可以填充整个对象树,但是我没时间用完了。

希望它至少能够显示一个可能的解决方案,而无需编写大量冗长的代码来更新模型。

答案 2 :(得分:0)

如果您的需求适中,您可以使用简单的vanilla JS for循环来完成此操作。此示例假定您具有名为“myViewModel”的现有模型,以及名为“jsonData”的部分刷新数据:

for (var prop in jsonData) {
    if (myViewModel.hasOwnProperty(prop)) {
        myViewModel[prop](jsonData[prop]);
     }
}

由于它只是更新了值,因此您附加到可观察对象的任何其他属性都应保留在原位。