两次调用ko.mapping.fromJS是对的吗?

时间:2014-05-11 09:53:21

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

我正在使用knockout映射插件将JSON数据映射到knockout视图模型。问题是来自服务器数据的JSON并不总是具有所有属性。但我的计算出的obeservable引用了它们。因此,我使用空对象(templateStructure)在第一个映射中创建所有observable,包含所有属性,然后使用实际数据进行seocond调用,以使用当前数据填充observable。这工作正常,但想知道是否有更好的方法来处理这种情况?

这就是现在正在进行两次通话的方式。 templateStructure是一个dummay对象,所有属性和数据都是实际数据。

ko.mapping.fromJS(templateStructure, {}, this);
ko.mapping.fromJS(data, {}, this);

2 个答案:

答案 0 :(得分:0)

调用mapping.fromJS来更新现有的视图模型是正确的。如果您使用AJAX接收模型的更新,这是最简单的方法(如果您没有使用映射,则必须手动执行,属性为属性)。

您创建"模板视图模型的方法"所有属性都存在,即使你没有收到它们,它们仍然存在JSON响应是好的。此外,它更容易理解JavaScript代码:您不需要查看服务器端以发现视图模型中的哪些属性,如果您直接从服务器进行第一次映射就会发生这种情况。

但是,如果收到的模型接近完成,您可以随时customize the "create" of your mapping(您可以使用js hasOwnProperty查找缺少的可观察属性并添加缺失的属性)。链接中文档的最后一个示例如此精确地如何添加新的observable(在此示例中,是一个计算的observable):

var myChildModel = function(data) {
  ko.mapping.fromJS(data, {}, this); // this is the view model

  this.nameLength = ko.computed(function() { // nameLength is added to the vm
      return this.name().length;
  }, this);
}

在此示例中,只有在收到的数据中不存在时才可以添加创建nameLength的条件,如下所示:

if (!data.hasOwnProperty('nameLength')) { 
   /* add the missing observ. property here */
}

(注意:如果需要,您还可以自定义更新)。

答案 1 :(得分:0)

我通过在映射之前合并对象使用jQuery扩展方法解决了它。所以我只需要调用映射函数。

         var mergedData = jQuery.extend(true,data,templateStructure);
         ko.mapping.fromJS(mergedData, {}, this);