【问题标题】:Inconsistancy with knockout and mapping .toJS helper methods与敲除和映射 .toJS 辅助方法不一致
【发布时间】:2016-02-10 09:17:29
【问题描述】:

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

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

【问题讨论】:

  • 简短回答,如果你打算使用映射插件来映射你的模型,你需要使用映射插件来取消映射。插件需要能够工作的大量元数据,其中很多是使用不打算使用的对象上的特殊属性存储的。 Vanilla 淘汰赛没有意识到这一点,因此它只会将元数据视为普通数据。
  • 我只想将映射插件用于我的模型的一部分。在我的真实示例中,我有一个 isEditing 可观察标志。我不想通过我的数据发送这个,因为它没有存储或我的域的一部分。也就是说,当我在整个事情上调用 .toJS 时,我需要知道它的价值。
  • @4imble 你应该用你对他的回答的删除评论来回答你的问题,因为你刚才描述的绝对是你(和我的)问题的答案。下面的答案没有解决您所描述的内容,您需要添加函数来返回您想要在映射后序列化的内容。谢谢你的注意!

标签: knockout.js knockout-mapping-plugin


【解决方案1】:

您要解释的是映射器的正常行为,它有一个解释:当您将模型绑定到视图时,只会绑定现有的可观察属性。如果稍后添加新的 observable 属性,它将不起作用。视图只会知道绑定时存在的 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);

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

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

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

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

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

【讨论】:

  • 感谢您的详细解释。我现在有了更好的理解,但它对我来说似乎仍然不直观。我没有添加任何可观察的,我只是映射到现有的之一(据说应该只更新它已经存在的值)。我觉得奇怪的是,在进行映射之前调用 ko.mapping.toJS 会序列化所有属性,但之后调用只会序列化映射的属性,尽管原始属性仍然存在并且可以从视图中绑定。
  • 正如我告诉你的,使用ko.mapping.fromJS,除了创建一个带有可观察对象的新对象外,还会在__ko_mapping__ 属性中存储一些配置。这使得 'ko.mapping.toJS' 具有与ko.toJS 不同的行为。如果您添加一些工作代码,我可以为您提供更准确的信息。如果有进一步的疑问,请尝试添加 conde sn-p 或 jsfiddel。
  • 我的问题末尾有一个 JSBin。我与与我一起工作的其他一些团队进行了交谈,他们通过在映射任何内容后立即删除__ko_mapping__ 属性来解决这个问题。然后他们使用ko.toJS
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2013-07-04
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 2013-07-17
  • 2023-03-29
相关资源
最近更新 更多