Knockout 2d可观察数组未更新

时间:2018-05-17 13:15:02

标签: javascript knockout.js

我有Json数据:

    "visualAttributes": {
           "stemAppearance": [
                "a",
                "b",
                "c",
                "k",
                "l"
           ],
           "foamAppearance": [
                "yellow",
                "red",
                "green",
                "blue",
                "grey",
           ],
           "adhesionAppearance": [
                "y",
                "y",
                "i",
                "o",
                "o"
           ],
           "stemAngle": [
                "z",
                "x",
                "c",
                "r",
                "v",
              ]
       }

在解析之后,我使用以下代码在我的视图模型中生成2d ObservableArray:

self.visualAttributes = ko.observableArray([]);

self.setVisualAttributes = function(visualAttributes) {
        for(attribute in visualAttributes) {

                var attr = ko.observableArray();
                for(var i=0; i<visualAttributes[attribute].length; i++) {
                     cell = ko.observable(visualAttributes[attribute][i]); 
                     attr.push(cell);

                }
            self.visualAttributes.push(attr);
            }

    }

我在HTML Table上通过以下方式呈现它:

    <tbody data-bind="foreach : $root.visualAttributes">

                                <tr>

                                <!-- ko foreach: $data -->
                                    <td><input type="text" class="form-control" data-bind="value: $data"></input></td>
                                <!-- /ko -->
                                </tr>
                            </tbody>

表格正确呈现,我能够看到值。但是,在编辑单元格中的任何值时,不会在self.visualAttributes()变量中更新数据。我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:1)

Knockout并没有真正处理嵌套的普通observable和value: $data ......最好是制作一个Cell属性value视图模型:

function Cell(value) { this.value = ko.observable(value); }

// In loop
var cell = new Cell(visualAttributes[attribute][i]);
attr.push(cell);

// In view
<input data-bind="value: value" />

这也是一个奇怪的工作,它确保你绑定到observable的实际引用,而不是unwrapped值:

const data = ko.observableArray([
  [ ko.observable("1"), ko.observable("2") ],
  [ ko.observable("a"), ko.observable("b") ]
])

ko.applyBindings({ data });

const unwrwappedData = ko.pureComputed(
  () => data().map(row => row.map(ko.unwrap))
)

unwrwappedData.subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>


<table>
  <tbody data-bind="foreach: data">
    <tr data-bind="foreach: $data">
      <td><input type="text" data-bind="value: $parent[$index()]"></td>
    </tr>
  </tbody>
</table>