knockoutjs ObservableArrays and sort function: UI is not updated
Asked Answered
B

1

6

In my viewmodel, I have a knockoutjs ObserableArray. Just after I initialized the ViewModel, it binds the data successfully. Then, what I need to do is to sort the collection.

$.each(vm.searchResults(), function (i, property) {
    console.log(property.Name());
});

vm.searchResults().sort(function (a, b) {
    return a.Name().toLowerCase() > b.Name().toLowerCase() ? 1 : -1;
});

$.each(vm.searchResults(), function (i, property) {
    console.log(property.Name());
});

As you can see, I output the Name of the element to the console to see the order before and after the sorting. The sorting works just fine. The problem is with the UI update. Somehow, the UI is not updated.

Then, try to remove a record from the array with the following code to see if the UI will respond to that or not:

vm.searchResults().shift();

The UI stays the the same and didn't update again. What would be the problem here?

Edit:

Here is a sample case as well: http://jsfiddle.net/tugberk/KLpwP/

The same problem here as well.

Edit:

I solved the problem as shown in this sample: http://jsfiddle.net/tugberk/KLpwP/16/ But I am still not sure why it worked as I tried at first.

Blessed answered 7/5, 2012 at 10:1 Comment(0)
Q
18

You're unwrapping observable array when you are going to sort it. This is causes problem, because KO can't track array was changed. ko.observableArray() has sort function with same signature and it will notify observable's subscribers that it has been changed. Solution is very simple: remove braces vm.searchResults().sort => vm.searchResults.sort. Checkout my example: http://jsfiddle.net/RbX86/

Another way to tell KO that array has changes - call valueHasMutated method after manipulations with array. Please review this sample: http://jsfiddle.net/RbX86/1/ This approach is very good when you need to make many changes in your array and you want to refresh UI only one time.

Q answered 7/5, 2012 at 10:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.