我正在使用ko.mapping.fromJS
将JSON数据应用于我的ViewModel。此JSON数据中包含嵌套对象,如下所示:
var data = {
item : "#1234",
description: "This is item #1",
moreinfo: {
condition: "Good"
}
}
当我尝试将新数据重新映射到对象时,它可以正常工作,更新所有值。但是,如果我将moreinfo
的值重新映射到null
,因为此项目没有moreInfo,如下所示:
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/
如果使用按钮#1应用了绑定,则使用#2映射空值,然后使用#3映射新值,您将看到我描述的问题。
如果使用Button#1 applyBindings,则使用#3映射新值,然后使用#4映射新值(这些值都不为空),它可以正常工作。
答案 0 :(得分:2)
Knockout绑定处理程序的工作方式是它们连接到一个observable,并且当可观察的更改时它们会响应。它不会绑定到您的绑定表达式,而是绑定到您的可观察对象所以您的绑定:
<p data-bind="text: moreinfo.condition"></p>
...获取condition
的{{1}}属性,这是一个可观察的对象并订阅它。当你这样做时:
moreinfo
...它的工作原理是因为Knockout可以将 var data4 = {
item : "#0000",
description: "This is item #4",
moreinfo: {
condition: "Meh"
}
}
ko.mapping.fromJS(data4, {}, viewModel);
的结构绑定到您的视图模型,并使用新值data4
更新完全相同的可观察对象。
如果你这样做:
'Meh'
...它没有更新那个observable,而是更新var data2 = {
item : "#4567",
description: "This is item #2",
moreinfo:null
}
$("#button2").on("click", function(){
ko.mapping.fromJS(data2, {}, viewModel);
});
属性,所以它是null。由于绑定是对可观察对象而不是表达式,因此即使更新视图模型使moreinfo
不再为null,也不会重新计算绑定表达式;你的DOM仍然绑定到同一个原始的可观察对象。
您可以通过将moreinfo
作为可观察对象,绑定到它,然后绑定到moreinfo
来解决此问题;这样,如果要么更新,您的DOM将按预期更新。例如:
condition