Yimin Rong
Yimin Rong

Reputation: 2027

Using Ext.util.Sortable to sort an array

I'd like to reuse the sorters of a store to create a comparison function to sort an array. Here's the code I have simplified:

// Data to sort
var data = [
    {rank: 2, name: 'Zebra'},
    {rank: 2, name: 'Aardvark'},
    {rank: 1, name: 'Lion'}
];

// Sort by rank, then by name, case-insensitive
var sorters = [
    {property: 'rank'},
    {property: 'name', transform: function(x) {return x.toLowerCase();}}
];

// Will need this
var util = Ext.create('Ext.util.Sortable');

// Normalize the sorters
var decoded = util.decodeSorters(sorters);

// Create a comparator
var comparator = util.createComparator(decoded);

// Sort the data using the comparator
// *** fails here in ExtJS 5 ***
Ext.Array.sort(data, comparator);

// Output
Ext.Msg.alert('Success', JSON.stringify(data));

Where it fails, it says this.sorterFn is not a function deep inside several layers of sorting related functions. Confirmed the above works perfectly in ExtJS 6.

It took a long time to get to this point, so before I get too much into the lower levels, is there an easier way to do this? That is, reuse sorters, intended for a data store, to sort data?

Or alternatively, is there perhaps a patch I can apply?

Upvotes: 1

Views: 733

Answers (1)

user2191247
user2191247

Reputation:

It's an issue in ExtJS 5.1.1 and earlier. Add this override as Sortable.js which fixes a scope-related bug, namely replaces this with sorters[i] in the for loop:

Ext.define('Ext.overrides.util.Sortable', { 
    override: 'Ext.util.Sortable', 
    createComparator: function(sorters) { 
        return sorters && sorters.length ? function(r1, r2) { 
            var result = sorters[0].sort(r1, r2), 
            length = sorters.length, 
            i = 1; 
            for (; !result && i < length; i++) {
                result = sorters[i].sort.call(sorters[i], r1, r2); 
            } 
            return result; 
        }: function() { 
            return 0; 
        }; 
    } 
}); 

Tested your code in ExtJS 5.0 and 5.1.0 and it works without problem.

Upvotes: 1

Related Questions