Knockout.js:对表和foreach中的值进行求和

时间:2015-03-19 15:38:11

标签: javascript html knockout.js knockout-2.0

带有数据绑定的表目前如下所示:

Source        Calls     ChargeableCalls

Car Insurance
08434599111     3            2
08934345122     2            1

Home Insurance
08734599333     3            2
08034345555     2            1

所需的输出应该与下面的示例相似,该表应包含按分组分组的CallsChargeableCalls的总值,以及所有{{的总值表格中有1}}和Calls

ChargeableCalls

以下是表格中的绑定:

Source          Calls         ChargeableCalls

Car Insurance
08434599154       3                  2
08934345555       2                  1
Total Calls       5     Total CC     3

Home Insurance
08434599154       6                  3
08934345555       1                  0
Total Calls       7     Total CC     3

Total Calls All  24     Total CC All 12

这是我的ViewModel:

<table class="table table-condensed" id="reportData">
<thead>
    <tr>
        <th>Source</th>
        <th>TotalCalls</th>
        <th>ChargeableCalls</th>
    </tr>
</thead>
<tbody data-bind="foreach: groups">
     <!-- ko foreach: $root.getGroup($data) -->
    <tr data-bind="if: $index() == 0">
        <td colspan="3" data-bind="text: division" class="division"></td>
    </tr>
    <tr>
        <td data-bind="text: source"></td>
        <td data-bind="text: totalCalls"></td>
        <td data-bind="text: chargeableCalls"></td>
    </tr>
    <!-- /ko -->
</tbody>

function GroupedReportingViewModel() { var self = this; self.results = ko.observableArray(); self.groupedResults = {}; self.getGroup = function (group) { return self.groupedResults[group]; }; self.groupedResultsC = ko.computed(function () { self.groupedResults = {}; ko.utils.arrayForEach(self.results(), function (r) { if (!self.groupedResults[r.division]) self.groupedResults[r.division] = []; self.groupedResults[r.division].push(r); }); return self.groupedResults; }); self.groups = ko.computed(function () { var g = []; for (x in self.groupedResultsC()) g.push(x); return g;_ }); } var model = new GroupedReportingViewModel(); ko.applyBindings(model); observableArray从ajax响应中填充,如下所示:

results

success: function (jsondata) { model.results(jsondata["Data"]["Report"]); } 对象如下所示:

jsondata

问:如何实现所需的输出?

1 个答案:

答案 0 :(得分:4)

在您的示例中,groupedResults是一个数组列表。而不是这样,尝试为一个组创建一个ViewModel。然后可以使用此ViewModel来计算总计。例如......

function GroupViewModel(division) {
    var self = this;
    self.Division = division;
    self.Items = ko.observableArray();
    self.Count = ko.computed(function() { 
        var count = 0;
        ko.utils.arrayForEach(self.Items(), function(r) { count += r.totalCalls; });
        return count; 
    });
    self.ChargeableCount = ko.computed(function() { 
        var count = 0;
        ko.utils.arrayForEach(self.Items(), function(r) { count += r.chargeableCalls; });
        return count; 
    });
}

您也可以简化主Viewmodel,并将项目推送到GroupViewModel中:

function GroupedReportingViewModel() {
    var self = this;
    self.results = ko.observableArray();
    self.groupedResults = ko.computed(function() {
        var groups = [];
        ko.utils.arrayForEach(self.Results(), function(r) {
            var g = ko.utils.arrayFirst(groups, function(g) { return g.Division === r.division; });
            if (!g) {
                g = new GroupViewModel(r.division);
                groups.push(g);
            }
            g.Items.push(r);
        });
        return groups;
    });
    self.TotalCount = ko.computed(function() { 
        var count = 0;
        ko.utils.arrayForEach(self.results(), function(r) { count += r.totalCalls; });
        return count; 
    });
    self.TotalChargeableCount = ko.computed(function() { 
        var count = 0;
        ko.utils.arrayForEach(self.results(), function(r) { count += r.chargeableCalls; });
        return count; 
    });
}

最后在您的视图中,遍历组,然后遍历项目:

<tbody>
    <!-- ko foreach: groupedResults -->
    <tr>
        <td colspan="3" data-bind="text: Division" class="division"></td>
    </tr>
    <!-- ko foreach: Items -->
    <tr>
        <td data-bind="text: source"></td>
        <td data-bind="text: totalCalls"></td>
        <td data-bind="text: chargeableCalls"></td>
    </tr>
    <!-- /ko -->
    <tr>
        <td>Total Calls</td>
        <td data-bind="text: Count"></td>
        <td>Total Chargeable:</td>
        <td data-bind="text: ChargeableCount"></td>
    </tr>
    <!-- /ko -->
    <tr>
        <td>Total Calls All</td>
        <td data-bind="text: TotalCount"></td>
        <td>Total Chargeable All</td>
        <td data-bind="text: TotalChargeableCount"></td>
    </tr>
</tbody>