我一直在网上搜索,似乎我不能在我的可观察数组上进行排序。我在某个地方肯定是错的,但不确定在哪里,这是代码:
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
但不起作用。我不想让按钮被调用来对我的数据进行排序,我希望它们在呈现之前进行排序。
答案 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"));
});