我在人物对象的Knockout中有一个可观察的数组.我希望能够根据姓氏对人员列表进行排序.问题是该列表有许多重复的姓氏.结果是,当有多个姓氏时,名字会在找到时显示.我希望能够按姓氏对数组进行排序,并且当有多个姓氏时,还要按名字排序.我正在使用文本输入让用户开始输入姓氏.结果绑定到显示所有匹配项的模板.
<input data-bind="value: filter, valueUpdate: 'afterkeydown'">
这是我的Knockout数组过滤器代码:
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);
});
});
Run Code Online (Sandbox Code Playgroud)
对于姓氏过滤,这工作正常,但是当有重复的姓氏时,我无法找到添加排序名字的方法.例如,在我的数组中按姓氏排序时我得到:
Joe Bailey
Jack Brown
Adam Brown
Bob Brown
Jim Byrd
Run Code Online (Sandbox Code Playgroud)
我希望重复的姓氏也可以排序他们的名字:
Joe Bailey
Adam Brown
Bob Brown
Jack Brown
Jim Byrd
Run Code Online (Sandbox Code Playgroud)
Sha*_*son 102
KnockoutJS可观察数组提供了一个排序函数,这使得在UI中对数据绑定数组进行排序相对容易(无论数据的自然顺序如何.)
data-bind="foreach: items.sort(function (l, r) { return l.lastName() > r.lastName() ? 1 : -1 })"
Run Code Online (Sandbox Code Playgroud)
您不必对源数据进行预排序/重新排序,如果您在绑定之前进行排序(或由于排序而重新绑定),那么您做错了.
那就是说,你要问的是按两个数据,姓氏,然后是名字排序.
而不是"l.lastName()> r.lastName()?1:-1"而不是考虑以下内容:
l.lastName() === r.lastName()
? l.firstName() > r.firstName() ? 1 : -1
: l.lastName() > r.lastName() ? 1 : -1
Run Code Online (Sandbox Code Playgroud)
我敢肯定,这可能更有效率.基本上你有三个条件:
我已经扫描了你的代码,我发现没有这样的排序功能.
这与Michael Best的答案类似,但是,我试图澄清WHERE来处理排序(在你的绑定中,第一个例子)和如何实现你正在寻找的排序(多个数据).
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) })"
Run Code Online (Sandbox Code Playgroud)
当然,当您引入更多排序向量(例如反转或其他数据)时,这可能变得难以处理,因此您应该实现一个过滤函数,为您执行上述评估:
data-bind="foreach: items().sort(my.utils.compareItems)"
Run Code Online (Sandbox Code Playgroud)
如果您确保players.json返回的名称已排序,那就没问题了。如果它从数据库加载它们,您需要将名字字段添加到您的ORDER BY子句中。
如果您想在 Javascript 中进行排序,您可以在从服务加载后立即进行:
players.sort(function(player1, player2) {
return player1.lastname.localeCompare(player2.lastname) ||
player1.firstname.localeCompare(player2.firstname);
});
Run Code Online (Sandbox Code Playgroud)