Knockout.js ObservableArray sort not updating UI
Asked Answered
E

2

7

I have a Knockout observable array that refuses to update the UI (a jquery Accordion) to which it is bound after a .sort() call, but happily updates the UI after a .reverse() call - I've been banging my head against this problem for days - can't seem to find an answer... help!

Container View Model - implements the observableArray Property :

function DataTextsKOViewModel( jsonTexts  ) {
    var self = this;

    // Texts array 
    self.texts = ko.observableArray();

    // Build from json data array 
    for (var i = 0; i < jsonTexts.AuthorityTexts.length; i++) {
        var jsontext = jsonTexts.AuthorityTexts[i];
        // Push Text VModel objects onto the KO observable array list ..
        self.texts.push(
                new DataTextKOViewModel( jsontext )
           );
    }

}

Array Object Model - These are the objects which are sorted:

// Single data text view model
function DataTextKOViewModel(jsonText) {
    // Other properties omitted for brevity 
    this.ListOrder = ko.observable(jsonText.ListOrder);
}

Custom Sort Function :

function textListOrderCompare(l, r) {

// Ascending sort
var retval = ((l.ListOrder() == r.ListOrder()) ? 0 
: ((l.ListOrder() > r.ListOrder()) ? 1 : -1));

return retval;
}

Binding Markup :

<!-- ko foreach: texts -->    
<div class="group" data-bind="attr:{'id': clientId() }">   
     <h3 data-bind="attr:{'dataKey': responsibilityId() }">
        <span data-bind="text: responsibilitySectionHeader"></span>
     </h3>    
     <div>
        <!-- section content goes here -->
     </div>
</div>  

When User Elects to sort:

myDataTextsKOViewModel.rollbackChanges();
dataTextsViewModel.texts.sort(textListOrderCompare);  
// UI Never updates - but I've checked console output to ensure that the array 
/ /sorts correctly

dataTextsViewModel.texts.sort(textListOrderCompare);  
// UI updates with items in reverse order 

Any help you can give me would be most appreciated.

EDIT: Should have mentioned - I already call valueHasMutated() on the observable array property after the .sort()! - Andrew

Ellita answered 11/11, 2013 at 13:44 Comment(0)
S
4

Try to call valueHasMutated function after sorting:

dataTextsViewModel.texts.sort(textListOrderCompare); 
dataTextsViewModel.texts.valueHasMutated();
Sancho answered 11/11, 2013 at 13:53 Comment(0)
V
1
dataTextsViewModel.texts(dataTextsViewModel.texts().sort(textListOrderCompare));

this way you change observable. Other way was changing the array inside and didn't trigger the change.

Vander answered 11/11, 2013 at 14:57 Comment(1)
Sorry - I've added the reassignment of the texts array as you suggested - but the UI still doesnt update ...Ellita

© 2022 - 2024 — McMap. All rights reserved.