【发布时间】:2017-01-28 12:53:16
【问题描述】:
我正在使用 ko.mapping.fromJS 将 JSON 数据应用到我的 ViewModel。此 JSON 数据中有嵌套对象,如下所示:
var data = {
item : "#1234",
description: "This is item #1",
moreinfo: {
condition: "Good"
}
}
当我尝试将新数据重新映射到对象时,它可以正常工作,更新所有值。但是,如果我将moreinfo 的值重新映射为null,因为该项目没有更多信息,如下所示:
var data2 = {
item : "#4567",
description: "This is item #2",
moreinfo:null
}
它不会更新 DOM,而是保留之前的值 condition:"Good"。如果我再一次将值更新为具有moreinfo 的数据,如下所示:
var data3 = {
item : "#7890",
description: "This is item #3",
moreinfo: {
condition: "Bad"
}
}
它仍然会更新项目和描述,但它仍然不会更新 DOM,而是保留值 condition:"Good"。
我是在错误地使用映射,还是您不能让值变为null?
Javascript:
var viewModel;
$("#button1").on("click", function(){
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel, $("itemWrapper")[0]);
});
$("#button2").on("click", function(){
ko.mapping.fromJS(data2, {}, viewModel);
});
$("#button3").on("click", function(){
ko.mapping.fromJS(data3, {}, viewModel);
});
HTML:
<div id="itemWrapper">
<p data-bind="text: item"></p>
<p data-bind="text: description"></p>
<p data-bind="text: moreinfo.condition"></p>
</div>
<button id="button1">
Bind Data #1
</button>
<button id="button2">
Bind Data #2
</button>
<button id="button3">
Bind Data #3
</button>
JSfiddle:https://jsfiddle.net/hrgx5f1y/
如果您使用 Button #1 applyBindings,然后使用 #2 映射 null,然后使用 #3 映射新值,您将看到我描述的问题。
如果您使用 Button #1 applyBindings,然后使用 #3 映射新值,然后使用 #4 映射新值(这些都不是 null),它可以完美运行。
【问题讨论】:
-
一般提示:您不希望让 jQuery 在淘汰应用程序中进行任何顶级事件处理。唯一适合 jQuery 以任何方式接触 DOM 的地方(即附加到事件、修改 CSS 类、创建 HTML)是在自定义绑定处理程序中。所有主要的事件处理和 DOM 操作都应该通过敲除绑定来完成。
-
@Tomalak 感谢您的建议,这只是一个快速的模型,以便人们可以参考。真正的应用程序只在 ajax 调用之后映射数据,虽然我认为这仍然是一个 jQuery 事件。
-
这就是为什么我说“以任何方式触及 DOM”。使用 jQuery 作为您的 Ajax 库很好。关键是您不希望 jQuery 在没有 Knockout 控制的情况下修改 DOM。 (只是为了它,这里有一个没有映射插件的变体:jsfiddle.net/hrgx5f1y/2)
标签: javascript json knockout.js knockout-mapping-plugin