Knockout不会更新使用ko.mapping制作的模型中的字符串数组

时间:2013-05-21 18:08:44

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

以下是有问题的jsfiddle:http://jsfiddle.net/a28aP/5/

视图模型:

{
 "pitalice": [{
     "pitanje": "Kako se zove rezultat koji se dobija deljenjem dva broja",
     "ponudjeno": ["Kolicnik", "Suma", "Proizvod"],
     "tacan": 0
 }, {
     "pitanje": "Limonit je ruda",
     "ponudjeno": ["Aluminijuma", "Olova", "Gvožda"],
     "tacan": 2
 }, {
     "pitanje": "Ko je komponovao operu 'Samson I Dalila'",
     "ponudjeno": ["Žorž Bize", "Ðuzepe Verdi", "Kamij Sen-Sans"],
     "tacan": 2
 }, {
     "pitanje": "Ko je autor satiricnih pripovedaka 'Danga', 'Kraljevic Marko po drugi put medu Srbima' i drugih",
     "ponudjeno": ["Milovan Glišic", "Laza Lazarevic", "Radoje Domanovic"],
     "tacan": 2
 }, {
     "pitanje": "Koje godine je u Atini održana prva Olimpijada 'modernog doba'.",
     "ponudjeno": ["1896.", "1898.", "1900."],
     "tacan": 0
 }]

};

HTML:

<div data-bind="foreach: pitalice" class="divPitalice">
<div class="divPitanje">
    <input type="text" data-bind="value: pitanje" style="width: 600px" />
    <div data-bind="foreach: ponudjeno">
        <input type="text" data-bind="value: $data" />
        <input type="radio" data-bind="attr: { name: $parentContext.$index, value: $index }, checked: $parent.tacan" />
        <br />
    </div>
</div>

正如您所见,大文本框的更改很好地传播到视图模型。

但是,如果更改较小的文本框并单击“保存”,则这些更改不会保存在视图模型中。

为什么?

谢谢!

3 个答案:

答案 0 :(得分:3)

ko.mapping插件仅映射数组和对象(它们分别成为observableArray和observable)。你的答案数组是纯字符串,不被视为对象。

只需将字符串数组转换为对象数组:

var dataObj = {
    "pitalice": [{
        "pitanje": "Kako se zove rezultat koji se dobija deljenjem dva broja",
        "ponudjeno": [ { text: "Kolicnik" }, { text: "Suma" }, { text: "Proizvod" } ],
        "tacan": 0
    },
    .....

http://jsfiddle.net/a28aP/11/

答案 1 :(得分:1)

不确定是什么问题,它可能与observableArrays有关,但heres a JSFiddle有解决方法。

我基本上将你的数组项包装在这样的对象中:

 var dataObj = {
 "pitalice": [{
     "pitanje": "Kako se zove rezultat koji se dobija deljenjem dva broja",
     "ponudjeno": [{ name: "Kolicnik" }, { name: "Suma"}, { name: "Proizvod"}],
     "tacan": 0
 }, {
     "pitanje": "Limonit je ruda",
     "ponudjeno": [{ name: "Aluminijuma"}, { name: "Olova"}, { name: "Gvožda"}],
     "tacan": 2
 }, {
     "pitanje": "Ko je komponovao operu 'Samson I Dalila'",
     "ponudjeno": [{ name: "Žorž Bize"}, { name: "Ðuzepe Verdi"}, { name: "Kamij Sen-Sans"}],
     "tacan": 2
 }, {
     "pitanje": "Ko je autor satiricnih pripovedaka 'Danga', 'Kraljevic Marko po drugi put medu Srbima' i drugih",
     "ponudjeno": [{ name: "Milovan Glišic"}, { name: "Laza Lazarevic"}, { name: "Radoje Domanovic"}],
     "tacan": 2
 }, {
     "pitanje": "Koje godine je u Atini održana prva Olimpijada 'modernog doba'.",
     "ponudjeno": [{ name: "1896."}, { name: "1898."}, { name: "1900."}],
     "tacan": 0
 }]
};

并在HTML中将$ data更改为$ data.name:

<h2>Pitalice</h2>
  <div data-bind="foreach: pitalice" class="divPitalice">
  <div class="divPitanje">
    <input type="text" data-bind="value: pitanje" style="width: 600px" />
    <div data-bind="foreach: ponudjeno">
        <input type="text" data-bind="value: $data.name" />
        <input type="radio" data-bind="attr: { name: $parentContext.$index, value: $index}, checked: $parent.tacan" />
        <br />
      </div>
    </div>
  </div>
  <button onclick="alert(ko.mapping.toJSON(window.kViewModel));">Save</button>

答案 2 :(得分:0)

欢迎来到SO!

它不会跟踪值的更改,因为它们不是对象或属性,而只是字符串列表。所以没有什么可以更新的。我分叉你的jsfiddle,并将它从一个字符串列表更改为一个具有name属性的对象列表,并正确更新。以下是更新的fiddle和以下示例:

 {
     "pitanje": "Kako se zove rezultat koji se dobija deljenjem dva broja",
     "ponudjeno": [{name:"Kolicnik"}, {name:"Suma"}, {name:"Proizvod"}],
     "tacan": 0
 },