Search code examples
javascriptbackbone.jsunderscore.js

Stop collection from sorting itself but still able to sort i


I have a problem, I seeked help in #documentcloud on Freenode and got some suggestions but still hasn't helped me fix my problem.

Basically I have a collection, very large up to 2-3 thousand items, and it -has- to be sorted, however it only has to be sorted at certain times. Using a comparator function is fine, it keeps it sorted, but takes a lot longer when all the items are being added to the collection, as it's resorting the entire collection each time one of the 2-3000 items are added.

I've tried a couple of suggestions, one being:

collection.comparator = function(object) { object.get('sortBy'); };
collection.sort();
collection.comparator = undefined;

This fails miserably and doesn't sort at all, I've also tried using collection.sortBy(...) this seems to return the sorted collection, but it is of no use to me as when I try collection = collection.sortBy(...) it just dumps the sorted collection as an array into the variable collection. When I try to use collection functions or utilities I get errors like .each is undefined for collection, etc.

Any ideas?


Solution

  • This can't be done simply because Collection.sort actually calls Collection.comparator.

    You have basically three options

    Option One

    You could force your sort method without comparator to the models itself ( basically the same as calling .sort of your collection, but without .comparator

    // in your collection class
    
    _comparator: function(a,b) { /* comparator code */ }
    
    sorter: function() {
       // Of course you should bind this to your collection at this function 
       // and your comparator
    
       this.models.sort( _comparator ) // .models gives you the array of all models
    }
    

    Option Two

    Remove comparator each time you add something to the collection

    _comparator = function(a,b) { /* comparator code */ }
    collection.comparator = undefined
    collection.fetch({ success: function() { collection.comparator = _comparator })
    

    Options Three

    If you think a little bit ahead of your code, and simply want your collection sorted only because you want to display it this way, you could simply sort it on display

    collection.returnSorted = function () { return collection.sortBy( _comparator ) }