【问题标题】:KnockoutJS observableArray: group data in foreachKnockoutJS observableArray:在foreach中分组数据
【发布时间】:2015-05-18 16:14:41
【问题描述】:

带有 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>

【问题讨论】:

  • 您在页面的哪个位置调用 ko.applybindings()?

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


【解决方案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);

【讨论】:

  • 我应该把这个计算字段放在哪里,绑定在我的表中看起来如何?
  • 当您声明您的 ReportingViewModel 时,会创建更多的 js 函数,因此当您调用它时,您可以将计算对象包含为属性。
  • 我在将它集成到我的视图中时遇到了困难,你能帮忙吗?使用我的更多代码查看编辑。
【解决方案2】:

这是一个合理的关于在 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;
};    

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

【讨论】:

    猜你喜欢
    • 2012-04-10
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多