Reputation: 2027
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
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