在 Knockout 中对 Observable 数组进行排序 [英] Sorting an Observable Array in Knockout

查看:23
本文介绍了在 Knockout 中对 Observable 数组进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在人类对象的淘汰赛中有一个可观察的数组.我希望能够根据姓氏对人员列表进行排序.问题是该列表有许多重复的姓氏.结果是,当有多个姓氏时,第一个名字会按原样显示.我希望能够按姓氏对数组进行排序,并且当有多个姓氏时,还可以按名字对其进行排序.我正在使用文本输入让用户开始输入姓氏.结果绑定到显示所有匹配项的模板.

I have an observable array in Knockout of person objects. I wanted to be able to sort the list of persons based on the last name. The problem is the list has a number of duplicate last names. The result is that when there are more than one last name, the first names appear as they were found. I'd like to be able to sort the array by last name and when there are more than one last name, have it also sort by first name. I'm using a text input for the user to start typing in the last name. The results are bound to a template that displays all the matches.

这是我的 Knockout 数组过滤器代码:

And here is my Knockout array filter code:

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);
    });    
});

对于姓氏过滤,这可以正常工作,但是当姓氏重复时,我无法找到添加排序名字的方法.例如,在我的数组中按姓氏排序时得到:

For last name filtering this works fine, but I'm unable to find a way to add in sorting first name when there are duplicate last names. For example, in my array when sorted by last name I'm getting:

Joe Bailey
Jack Brown
Adam Brown
Bob Brown
Jim Byrd

我希望对重复的姓氏也进行排序:

I'd like the duplicate last names to have their first names sorted as well:

Joe Bailey
Adam Brown
Bob Brown
Jack Brown
Jim Byrd

推荐答案

KnockoutJS 可观察数组提供了一个排序功能,这使得在 UI 中对数据绑定数组进行排序变得相对容易(无论数据的自然顺序如何.)

KnockoutJS observable arrays offer a sort function, this makes it relatively easy to sort a databound array in your UI (regardless of the natural order of the data.)

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

您不应该对源数据进行预排序/重新排序,如果您在绑定之前进行排序(或由于排序而重新绑定),那么您就做错了.

You should not have to pre-sort/re-sort your source data, if you're sorting before binding (or rebinding due to a sort) then you're doing it wrong.

也就是说,您要求的是按两个数据排序,姓氏,然后是名字.

That said, what you're asking is to sort by two datum, last name, then first name.

代替l.lastName() > r.lastName() ? 1 : -1"考虑以下内容:

Instead of "l.lastName() > r.lastName() ? 1 : -1" consider the following:

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

这可能会更有效率,我敢肯定.基本上你有三个条件在起作用:

This could be more efficient, I'm sure. Basically you have three conditionals at play:

  1. 姓氏是否相同?
  2. 如果是,比较名字并返回结果.
  3. 否则,比较姓氏并返回结果.

我已经扫描了您的代码,但我发现没有这样的排序功能.

I've scanned your code and I see no such sort function in place.

这类似于 Michael Best 的回答,但是,我试图阐明在何处处理排序(在您的绑定中,第一个示例中)以及如何实现您正在寻找的排序(多个数据).

This is similar to Michael Best's answer, however, I've attempted to clarify WHERE to handle sorting (in your binding, first example) and HOW to achieve the sort you're looking for (multiple datum.)

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) })"

当然,当您引入更多排序向量(例如反转或附加数据)时,这会变得很笨拙,因此您应该实现一个过滤器函数来为您执行上述评估:

Naturally, this can get unwieldy as you introduce more sort vectors, such as reversals or additional datum, and so you should implement a filter function that performs the above evaluation for you:

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

这篇关于在 Knockout 中对 Observable 数组进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆