在Knockout中对可观察数组进行sorting

我有一个可观察的数组在人对象的淘汰赛。 我希望能够根据姓氏对人员名单进行sorting。 问题是该列表有许多重复的姓氏。 结果是,当有多个姓氏时,姓氏显示为他们被发现的名字。 我希望能够按姓氏sorting数组,当有多个姓氏时,也可以按名字sorting。 我为用户使用文本input来开始input姓氏。 结果绑定到显示所有匹配的模板。

<input data-bind="value: filter, valueUpdate: 'afterkeydown'">

这里是我的淘汰arraysfilter代码:

 function Item(firstname, lastname) { this.firstname = ko.observable(firstname); this.lastname = ko.observable(lastname); } var playersViewModel = { items: ko.observableArray([]), filter: ko.observable("") }; var players; $(function() { playersViewModel.filteredItems = ko.computed(function() { var filter = this.filter().toLowerCase(); if (!filter) { return this.items(); } else { return ko.utils.arrayFilter(this.items(), function(item) { return ko.utils.stringStartsWith(item.lastname().toLowerCase(), filter); }); } }, playersViewModel); $.getJSON('./players.json', function(data) { players = data.players; playersViewModel.players = ko.observableArray(players); ko.applyBindings(playersViewModel); var mappedData = ko.utils.arrayMap(players, function(item) { return new Item(item.firstname,item.lastname); }); playersViewModel.items(mappedData); }); }); 

对于姓氏过滤这工作正常,但我无法find一种方法来添加sorting名字时有重复的姓氏。 例如,在我的数组中,当按姓氏sorting时,我得到:

 Joe Bailey Jack Brown Adam Brown Bob Brown Jim Byrd 

我想重复的姓氏也有他们的名字sorting:

 Joe Bailey Adam Brown Bob Brown Jack Brown Jim Byrd 

KnockoutJS可观察数组提供了一个sorting函数,这使得在UI中sorting数据绑定数组相对容易(不pipe数据的自然顺序如何)。

 data-bind="foreach: items.sort(function (l, r) { return l.lastName() > r.lastName() ? 1 : -1 })" 

如果你在绑定之前进行sorting(或者由于sorting而重新绑定),那么你不应该对源数据进行预先sorting/重新sorting,那么你做错了。

也就是说,你要求的是按照两个数据,姓氏,名字sorting。

而不是“l.lastName()> r.lastName()?1:-1”考虑以下内容:

 l.lastName() === r.lastName() ? l.firstName() > r.firstName() ? 1 : -1 : l.lastName() > r.lastName() ? 1 : -1 

我敢肯定,这可能更有效率。 基本上你有三个条件:

  1. 姓是平等的吗?
  2. 如果是这样,比较名字并返回结果。
  3. 否则,比较姓氏并返回结果。

我已经扫描了你的代码,我看不到这样的sortingfunction。

这与Michael Best的答案类似,但是,我试图澄清WHERE处理sorting(在你的绑定,第一个例子),以及如何实现你正在寻找的sorting(多数据)。

 data-bind="foreach: items().sort(function (l, r) { return (l.lastName() == r.lastName()) ? (l.firstName() > r.firstName() ? 1 : -1) : (l.lastName() > r.lastName() ? 1 : -1) })" 

当然,当你引入更多的sorting向量时,这会变得很难处理,比如反转或附加数据,所以你应该实现一个筛选函数,为你执行上面的评估:

 data-bind="foreach: items().sort(my.utils.compareItems)" 

如果你确保你的players.json返回的名字sorting,你会没事的。 如果从数据库加载它们,则需要将第一个名称字段添加到ORDER BY子句中。

如果你想在Javascript中进行sorting,你可以在从服务中加载之后立即执行:

 players.sort(function(player1, player2) { return player1.lastname.localeCompare(player2.lastname) || player1.firstname.localeCompare(player2.firstname); }); 

我有一些问题试图sorting可观察数组,我没有看到我的代码中的任何结果。

在将新项目返回到数组之前,您需要先对通过ajax / getJSON请求收到的结果进行sorting。

这样,结果在作为新项目添加到可观察数组之前被sorting。 那么不需要在绑定中对它们进行sorting。

看下面的例子。

 players(ko.utils.arrayMap(result, function (item) { result.sort(function (l, r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1); }); return new Player(item); })); 
  1. 使用AJAX / getJSON获取数据
  2. 将该请求的结果sorting到您select的数组中

您必须使用两种sorting方式来执行此操作。首先按照姓氏sorting,然后根据姓氏sorting并在第二sorting中根据姓氏search如果两个以上的人具有相同的姓氏,则根据他们的名字在他们的位置进行sorting,使用一些标准的sortingalgorithm….