敲除js和排序问题

时间:2016-05-03 14:26:24

标签: javascript sorting knockout.js

我一直在网上搜索,似乎我不能在我的可观察数组上进行排序。我在某个地方肯定是错的,但不确定在哪里,这是代码:

var availableProducts = [{"Id":"1","Description":"Product 1","Rate":2956.00},{"Id":"3","Description":"Product 2","Rate":1518.00},{"Id":"2","Description":"Product 3","Rate":750.00}];

function productViewModel() {
    var self = this;
    self.products = ko.observableArray();
}

var productDetails = new productViewModel();
$(document).ready(function () {

    productDetails.products = (availableProducts);
    ko.applyBindings(productDetails, document.getElementById("product-edit"));

}

HTML看起来像这样:

<tbody data-bind="foreach: sortedProducts">
    <tr>
        <td><span data-bind="text: Description"></span></td>
        <td><span data-bind="currency: Rate"></span></td>
    </tr>
</tbody>

因为可以看到ID按顺序为1,3,2,我想对它们进行排序并按顺序显示它们,但我似乎无法对产品进行排序。我尝试在我的ViewModel

中添加以下内容
self.sortedProducts = function () {
    return self.products().sort(function (a,b) {
        return a.Id < b.Id ? -1 : a.Id > b.Id ? 1 : 0;
});

这不起作用,我尝试将相同的代码添加到“$(document).ready(...)”,除了用self替换productDetails但不起作用。我不想让按钮被调用来对我的数据进行排序,我希望它们在呈现之前进行排序。

1 个答案:

答案 0 :(得分:3)

排序功能看起来不错,但您应该检查 - 最好使用单元测试 - 您支持的浏览器是否真正了解compareFunction传递给Array.prototype.sort。这只是我刚才遇到的一个问题。

1)您正在使用本机数组ko.observableArray()覆盖availableProducts - 这会在使用getter语法self.products()访问属性时出错。

2)模板中的foreach绑定不起作用,因为你把它交给普通函数而不是可观察数组,我猜它实际上迭代了函数对象本身的属性(。length,.prototype,.hasOwnProperty等)。

3)我建议使用Knockout Projections库,以便在计划处理更大的数组时为数组添加有效的可观察处理。根据我在一个集合中超过1000个项目的经验,如果没有投影功能,UI就不像你想要的那样流畅。

我对此的看法是:

var availableProducts = [{"Id":"1","Description":"Product 1","Rate":2956.00},{"Id":"3","Description":"Product 2","Rate":1518.00},{"Id":"2","Description":"Product 3","Rate":750.00}];

function productViewModel() {
    var self = this;
    // In case you know the products at this stage you could just
    // specify it as the first argument
    self.products = ko.observableArray(/* [{...}] */);

    // The sorted products are computed from the original ones
    self.sortedProducts = ko.computed(function () {
        // I'd probably use explicit parens for better 
        // readability - I had to look twice to get the comparer :-)
        return self.products().sort(function (a, b) {
            return a.Id < b.Id ? -1 : (a.Id > b.Id ? 1 : 0);
        });

        //// With ko-projections this would become:
        //// (note the missing parens on `products`)
        //return self.products.sort(function (a, b) {
        //    return a.Id < b.Id ? -1 : a.Id > b.Id ? 1 : 0;
        //});
    });  
}

var productDetails = new productViewModel();
$(document).ready(function () {
    // Set the observable array value 
    productDetails.products(availableProducts);
    ko.applyBindings(productDetails, document.getElementById("product-edit"));

});