0

我有一个像这样的简单示例数据

var data = {
    "Lines": [
        {"Entries": [{"Hours": 5.5},{"Hours": 2.50},{"Hours": 3.75}]}, 
        {"Entries": [{"Hours": 5.1},{"Hours": 2.00},{"Hours": 4.75}]},
        {"Entries": [{"Hours": 1.2},{"Hours": 3.00},{"Hours": 2.12}]
    }]
}

这是我的模型

function ViewModel() {
    var self = this
    self.List = ko.observableArray([])

    self.LoadData = function () {
        var data = {
            "Lines": [
                {"Entries": [{"Hours": 5.5},{"Hours": 2.50},{"Hours": 3.75}]}, 
                {"Entries": [{"Hours": 5.1},{"Hours": 2.00},{"Hours": 4.75}]},
                {"Entries": [{"Hours": 1.2},{"Hours": 3.00},{"Hours": 2.12}]
            }]
        }
        self.List(ko.mappings.fromJS(data.Lines))
    ////this makes every child observable
    }
    self.LoadData()
}

$('document').ready(function () {
    ko.applyBindings(new ViewModel())
}) 

这是我的看法

<table id="myTable" class="tablesorter">
    <thead>
        <tr>
            <th>Mon  1 </th>
            <th>Mon  2 </th>
            <th>Mon  3 </th>
        </tr>
    </thead>
    <tbody data-bind='foreach:Lines'>
        <tr data-bind='foreach:$data.Entries'>
            <td>
                <input type="text" data-bind="value:Hours"/>
            </td>
        </tr>
    </tbody>
</table>

这是示例视图

在此处输入图像描述

这是我想要的输出

在此处输入图像描述

您可以看到我正在添加需要添加的列和行,这些应该是可观察的。我该怎么做。我不知道从哪里开始。

4

2 回答 2

3

您只需要为每一行添加一个 computedObservable(更新的小提琴:http: //jsfiddle.net/kL79d/4/):

html:

<table id="myTable" class="tablesorter">
    <thead>
        <tr>
            <th>Mon  1 </th>
            <th>Mon  2 </th>
            <th>Mon  3 </th>
            <th>Total </th>
        </tr>
    </thead>
    <tbody data-bind='foreach:List'>
        <tr>
            <!-- ko foreach:Entries-->
            <td>
                <input type="text" data-bind="value:Hours, valueUpdate:'afterkeydown'"/>
            </td>
            <!-- /ko -->
            <td>
                <span data-bind="text:Total"></span> 
            </td>
        </tr>
    </tbody>
</table>

js:

function ViewModel() {
    var self = this
    self.List = ko.observableArray([])

    self.LoadData = function () {
        var data = {
            "Lines": [
                {"Entries": [{"Hours": 5.5},{"Hours": 2.50},{"Hours": 3.75}]}, 
                {"Entries": [{"Hours": 5.1},{"Hours": 2.00},{"Hours": 4.75}]},
                {"Entries": [{"Hours": 1.2},{"Hours": 3.00},{"Hours": 2.12}]
            }]
        }                       
        self.List(ko.mapping.fromJS(data.Lines)())
    ////this makes every child observable
    }

    self.applyTotals = function(){
        ko.utils.arrayForEach(self.List(), function(vm){
            vm.Total = ko.computed(function(){
                var s = 0;
                ko.utils.arrayForEach(this.Entries(), function(entry){
                    var p = parseFloat(entry.Hours(), 10);
                    if (!isNaN(p)) {
                        s += p;
                    }
                });
                return s;
            }, vm);
        });
    }

    self.LoadData();
    console.log(self.List());
    self.applyTotals();
}

ko.applyBindings(new ViewModel())

要获得列总数,请在垂直方向上执行相同的操作。为了更轻松地访问数据值,您可能希望将数据保留在允许对行和列进行轻松迭代的数据结构中。

于 2013-10-30T11:51:47.563 回答
3

映射插件的文档中,有一个名为“使用'create'自定义对象构造”的部分。这显示了如何控制 json 数据到可观察对象的映射——包括使用附加功能增强对象(如提到的 computedObservable @pax162)。

这与@pax162 提到的方法基本相同,但采用了更自动化的方式。

于 2013-10-30T11:59:59.933 回答