Knockout.js表按值和按字母顺序排序

时间:2017-01-18 20:03:06

标签: jquery html arrays sorting knockout.js

我有一个数据表,我已经设置了一个敲除绑定处理程序,它会在单击a时对表的数据进行排序。我可以按值排序,但问题是当一组数据是相同的值时,我需要表格然后按名称列按字母顺序对该分组进行排序。这是淘汰赛(打字稿):

ko.bindingHandlers["sort"] = {
    init: (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) => {
        var ascending = false;
        element.onclick = () => {
            var value = valueAccessor();
            var array = value.arrayName;
            var key = value.key;
            ascending = !ascending;

            array.sort(function (first, last) {
                var left = first;
                var right = last;
                if (!ascending) {
                    left = last;
                    right = first;
                }
                var keys = key.split('.');
                for (var i in keys) {
                    var keyName = keys[i];
                    var parentIndex = keyName.indexOf('()');
                    if (parentIndex > 0) {
                        keyName = keyName.substring(0, parentIndex);
                        left = left[keyName]();
                        right = right[keyName]();
                    } 
                    else {
                        left = left[keyName];
                        right = right[keyName];
                    }
                 }
                 return left == right ? 0 : left < right ? -1 : 1;
                });
            };
        }
    };
}

我的表格HTML:

<table class="table" id="largeTable">
<thead>
    <tr>
        <th data-bind="sort: { arrayName: product, key: 'name' }">Name</th>
        <th data-bind="sort: { arrayName: product, key: 'type' }">Type</th>
        <th data-bind="sort: { arrayName: product, key: 'reviewsNumber()' }">Reviews</th>
        <th data-bind="sort: { arrayName: product, key: 'ratingNumber()' }">Ratings</th>
        <th data-bind="sort: { arrayName: product, key: 'priceNumber()' }">Price</th>
        <th data-bind="sort: { arrayName: product, key: 'date' }">Date</th>
        <th data-bind="sort: { arrayName: product, key: 'status' }">Status</th>
    </tr>
</thead>
<tbody>
    <!-- ko foreach: productOnPage -->
    <tr>
        <td><div data-bind="text: name"></div></td>
        <td><div data-bind="text: type"></div></td>
        <td><div data-bind="text: reviews"></div></td>
        <td><div data-bind="text: rating"></div></td>
        <td><div data-bind="text: price"></div></td>
        <td><div data-bind="text: date"></div></td>
        <td><div data-bind="text: status"></div></td>
    </tr>
    <!-- /ko -->
</tbody>

如果我有十个产品都有4星评级,那么我希望该表按名称属性对这十个进行排序。我怎么能这样做?

1 个答案:

答案 0 :(得分:0)

以下是我为实现此目的所做的更新:

ko.bindingHandlers["sort"] = {
init: (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) => {
    var ascending = false;
    element.onclick = () => {
        var value = valueAccessor();
        var array = value.arrayName;
        var key = value.key;
        ascending = !ascending;

        array.sort(function (first, last) {
            var left = first;
            var right = last;

            var leftName = first.name;
            var rightName = last.name;

            if (!ascending) {
                left = last;
                right = first;
            }
            var keys = key.split('.');
            for (var i in keys) {
                var keyName = keys[i];
                var parentIndex = keyName.indexOf('()');
                if (parentIndex > 0) {
                    keyName = keyName.substring(0, parentIndex);
                    left = left[keyName]();
                    right = right[keyName]();
                } 
                else {
                    left = left[keyName];
                    right = right[keyName];
                }
             }

             if (left > right ) {
                 return 1;
             }
             else if (left  < right ) {
                 return -1;
             }

             if (leftName < rightName) {
                 return -1;
             }
             else if (leftName > rightName) {
                 return 1;
             }
             else { 
                 return 0;
             }
            });
        };
    }
};

}