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

Partial mapping to existing object with Knockout JS

本文关键字:对象 映射 Knockout JS 使用      更新时间:2023-09-26

我有一个复杂的模型,其中包含大量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 以外的其他机制。

从 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);

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

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

它非常简单,除了将同名对象与其现有字段匹配之外,并没有做太多事情。我希望管理子对象的创建,以便它可以填充整个对象树,但唉,我没时间了。

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

如果你的需求不大,你可以用一个简单的香草JS循环来做到这一点。此示例假定您有一个名为"myViewModel"的现有模型,以及名为"jsonData"的部分刷新数据:

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

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