KnockoutJS observableArray:foreach中的组数据

时间:2015-03-16 13:59:47

标签: javascript html knockout.js html-table ko.observablearray

带有knockout.js绑定当前的表看起来像这样:

source   total   division
 00234   4506     div1
 30222    456     div2
 63321     23     div2
 40941    189     div1

所需的输出将如下所示。数据需要按division分组。

source   total   
div1
 00234   4506 
 40941    189 
div2
 30222    456
 63321     23

这是我的ViewModel:

var ReportingViewModel;
ReportingViewModel = { Results: ko.observableArray(null) }

ReportingViewModel通过ajax请求填充:

ReportingViewModel.Results(data["Data"]["Report"]);

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

修改
这是我的观点:

        <table class="table table-condensed" id="reportData">
            <thead>
                <tr>
                    <th>source</th>
                    <th>total</th>
                    <th>division</th>   
                </tr>
            </thead>
            <tbody data-bind="foreach: Results">
                <tr>
                    <td data-bind="text: source"></td>
                    <td data-bind="text: total"></td>
                    <td data-bind="text: division"></td>
                </tr>
            </tbody>
        </table>

<script type="text/javascript">

    $(document).ready(function () {

            ReportingViewModel.Results(null);
            e.preventDefault();
            var numbers = null;
            if ($('#numbersdd').find("option:selected").length > 0) {
                numbers = $('#numbersdd').find("option:selected");}

            if (numbers != null) {

                    $.ajax({
                        url: '/Reporting/ReportData.aspx',
                        type: 'POST',
                        data: numbers,
                        dataType: 'json',
                        contentType: "application/json",
                        success: function (data) {
                            ReportingViewModel.Results(data["Data"]["Report"]);
                        },
                        error: function () {
                            alert('Error Running Report');
                        }
                    });
            }
            else { alert('No Data!'); }
        });

        var ReportingViewModel;

        ReportingViewModel = {
            Results: ko.observableArray(null),              
        }
        ko.applyBindings(ReportingViewModel);
   });

</script>

2 个答案:

答案 0 :(得分:1)

这是在Knockout 2.0中对数据进行分组的一个合理的小提琴,它应该适合你。

http://jsfiddle.net/rniemeyer/mXVtN/

最重要的是,您应该转换数据,以便将分区作为循环的元素,并且每个分区都有一个返回匹配数据的计算子项。他碰巧在observableArray属性本身上使用了一个扩展来管理这个......

ko.observableArray.fn.distinct = function(prop) {
    var target = this;
    target.index = {};
    target.index[prop] = ko.observable({});    

    ko.computed(function() {
        //rebuild index
        var propIndex = {};

        ko.utils.arrayForEach(target(), function(item) {
            var key = ko.utils.unwrapObservable(item[prop]);
            if (key) {
                propIndex[key] = propIndex[key] || [];
                propIndex[key].push(item);            
            }
        });   

        target.index[prop](propIndex);
    });

    return target;
};    

然后在你的标记中,只需数据绑定就可以遍历你的部门。

答案 1 :(得分:1)

您可以像这样声明computed字段:

GroupedResults: ko.computed(function() {
    var result = {};
    var original = ReportingViewModel.Results();
    for (var i = 0; i < original.length; i++) { 
        var item = original[i];
        result[item.division] = result[item.division] || []; 
        result[item.division].push(item); 
    }

    return result;
})

此计算字段将返回如下对象:

{
    div1: [{source: 234, total: 4506, division: 'div1'}]
    div2: [{source: 30222, total: 456, division: 'div2'}]
}

正如您所看到的,每个属性都是一个分区,它包含与此分区相关的记录数组。

然后将视图绑定到这个新的计算字段。

如果您想在ReportingViewModel声明中创建计算机,请执行以下操作:

var ReportingViewModel = function(data) {
    var self = this;

    self.Results = ko.observableArray(data);

    self.GroupedResults = ko.computed(...)
}

然后你对对象的调用类似于你现在拥有它的方式......但不是。

var reportingViewModel = new ReportingViewModel(data["Data"]["Report"]);
ko.applyBindings(reportingViewModel);