Sorting an Observable Array in Knockout

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.

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. Are the last names Equal?
  2. If so, compare first names and return a result.
  3. Else, compare last names and return a result.

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

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

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)