【问题标题】:Partial mapping to existing object with Knockout JS使用 Knockout JS 部分映射到现有对象
【发布时间】:2012-06-08 10:24:52
【问题描述】:

我有一个复杂的模型,其中包含大量 ko.observable、ko.observableArray 和嵌套对象,其中包含更多这些 observables。

现在,最初我必须在每个模型中创建方法,这些模型组成了更大的模型,以获取 Json 数据,然后填充它的 observables。现在我尝试了 ko.mapping 插件,但是当我使用它时:

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

这似乎适用于大多数对象,但是我注意到,当我这样做时,它似乎完全覆盖了对象,并且因为我使用的是淘汰赛 js 验证,即:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    来自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);
    

    【讨论】:

    • 是的,我看到了这种用法,问题是我的对象结构树很大,而且这种方法可能比我目前的方法更冗长,因为我目前的方法是每个对象都有一个“PopulateFromData(jsonData)”样式方法。我希望完全消除对此的需求,所以我可以调用 ko.mapping.fromJS(data, existingObject) 并且它不会仅仅改变值的结构......也许我可以根据淘汰赛编写自己的映射源代码,做类似 ko.mapping.updateValuesFromJS(data, existingObject);
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      如果您的需求不大,您可以使用一个简单的香草 JS for 循环来完成此操作。此示例假设您有一个名为“myViewModel”的现有模型,以及一个名为“jsonData”的部分刷新数据:

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

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

      【讨论】:

        猜你喜欢
        • 2012-03-23
        • 1970-01-01
        • 2012-11-17
        • 1970-01-01
        • 2013-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多