具有淘汰和映射。toJS辅助方法的Inconsistancy

时间:2015-11-09 16:46:54

标签: knockout.js knockout-mapping-plugin

我有一个视图模型,它有一些现有属性。

model.prop1 = ko.observable("");
model.prop2 = ko.observable("");

然后我将一些数据映射到此模型,该数据将更新prop1的值。

var data = {prop1: 'blah'};
ko.mapping.fromJS(data, {}, model);

当我致电ko.toJSko.mapping.toJS

时,我现在有些不一致

ko.toJS正如预期的那样序列化模型:

[object Object] {
  model: [object Object] {
    __ko_mapping__: [object Object] { ... },
    prop1: "blah",
    prop2: ""
  }
}

我使用了映射插件,因此它有一些我不想要的多余数据( ko_mapping )。

因此我使用ko.mapping.toJS,但这并不是序列化所有属性......只是已经映射的属性。 我的理解是,这会将所有内容序列化为ko.toJS吗?

[object Object] {
  model: [object Object] {
    prop1: "blah"
  }
}

这是预期的行为还是我发现了错误?

JSBin:https://jsbin.com/jupemoneri/6/edit?js,console

1 个答案:

答案 0 :(得分:1)

您要解释的是映射器的正常行为,它有一个解释:当您将模型绑定到视图时,只会绑定现有的可观察属性。如果稍后添加新的可观察属性,则无效。视图只会知道绑定时存在的observbale属性的变化。

因此,您需要修改第一次创建模型的方式,以便它包含所有必需属性。最简单的方法是使用具有所有属性的javascript对象,将其与从服务器接收的对象混合,然后使用ko.mapping.fromJs将其转换为模型。像这样:

// This is an empty object with all the excpected properties
var completeObject { a: null, b:null, c: null }; 

// "Mix in" the properties from the received, incompelte, object:
// An easy way to do it is using jquery https://api.jquery.com/jquery.extend/
$.extend(completeObject,incompleteObjectFromServer);

//使用映射创建视图模型:    var model = ko.mapping.fromJs(completeObject);

执行此操作后,您将获得一个“完整”模型,将所有必需属性转换为可观察属性,以便它们都可以绑定到视图。稍后使用映射插件时,这些可观察的属性将被正确更新,视图将对更改做出反应。

请注意,在执行映射时,除了observable之外,模型还包括最初映射对象时创建的配置,当您使用ko.mapping.fromJs()时,此配置将用于后续映射。< / p>

还有其他可能的技术可以获得相同的结果,例如:

  • 接收不完整的对象并“手动”包含缺失的属性
  • 为映射提供选项,以便按预期创建对象。请参阅ko.mapping docs
  • 中的选项部分
  • 修改服务器以使其返回“完整”对象。其余必需属性是否为null无关紧要,但它们必须位于返回的对象中。

注意:关于ko.toJS,它与映射无关:它只是返回一个新对象,其中提供的对象中的可观察属性转换为常规属性,其余属性保留为他们是。