在value设置为null之后,ko.mapping.fromJS不映射嵌套值

时间:2016-09-20 14:28:19

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

我正在使用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映射新值(这些值都不为空),它可以正常工作。

1 个答案:

答案 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