Reverse sort order with Backbone.js

前端 未结 15 899
不知归路
不知归路 2020-12-02 05:45

With Backbone.js I\'ve got a collection set up with a comparator function. It\'s nicely sorting the models, but I\'d like to reverse the order.

How can I sort the m

相关标签:
15条回答
  • 2020-12-02 06:10

    I had a slightly different requirement, in that I am displaying my models in a table, and I wanted to be able to sort them by any collumn (model property) and either ascending or descending.

    It has taken a fair amount of mucking around to get all the cases working (where values can be strings, empty strings, dates, numbers. However I think this is pretty close.

        inverseString: function(str)
        {
            return str.split("").map(function (letter) { return String.fromCharCode(-(letter.charCodeAt(0))); }).join("");
        }
        getComparisonValue: function (val, desc)
        {
            var v = 0;
            // Is a string
            if (typeof val === "string")
            {
                // Is an empty string, upgrade to a space to avoid strange ordering
                if(val.length === 0)
                {
                    val = " ";
                    return desc ? this.inverseString(val) : val;
                }                
    
                // Is a (string) representing a number
                v = Number(val);
                if (!isNaN(v))
                {
                    return desc ? -1 * v : v;
                }
                // Is a (string) representing a date
                v = Date.parse(val);
                if (!isNaN(v))
                {
                    return desc ? -1 * v : v;
                }
                // Is just a string
                return desc ? this.inverseString(val) : val;
            }
            // Not a string
            else
            {
                return desc ? -1 * val : val;
            }
        },
    

    use:

        comparator: function (item)
        {
            // Store the collumn to 'sortby' in my global model
            var property = app.collections.global.get("sortby");
    
            // Store the direction of the sorting also in the global model
            var desc = app.collections.global.get("direction") === "DESC";
    
            // perform a comparison based on property & direction
            return this.getComparisonValue(item.get(property), desc);
        },
    
    0 讨论(0)
  • 2020-12-02 06:12

    I read some where that the Backbone comparator function either uses or mimics the JavaScript Array.prototype.sort() function. This means it uses either 1, -1 or 0 to decide on the sort order of each model in the collection. This constantly updates and the collection stays in the correct order based on the comparator.

    Info on Array.prototype.sort() can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FArray%2Fsort

    Many answers on this question simply reverse the order just before rending it to the page. This is not ideal.

    Using the above article on Mozilla as a guide I was able to keep my collection sorted in reverse order using the following code, then we simply render the collection to page in it's current order and we can use a flag (reverseSortDirection) for reversing the order.

    //Assuming this or similar will be in your Backbone.Collection.
    sortKey: 'id', //The field name of the item in your collection
    
    reverseSortDirection: false,
    
    comparator: function(a, b) {
    
      var sampleDataA = a.get(this.sortKey),
          sampleDataB = b.get(this.sortKey);
    
          if (this.reverseSortDirection) {
            if (sampleDataA > sampleDataB) { return -1; }
            if (sampleDataB > sampleDataA) { return 1; }
            return 0;
          } else {
            if (sampleDataA < sampleDataB) { return -1; }
            if (sampleDataB < sampleDataA) { return 1; }
            return 0;
          }
    
    },
    

    Comparator except's two models, on changes to the collection or model the compartor function runs and changes the order of the collection.

    I have tested this approach with Numbers and Strings and it seems to be working perfectly for me.

    I really hope this answer can help as I have struggled with this problem many times and usually end up using a work around.

    0 讨论(0)
  • 2020-12-02 06:12

    I just overrode the sort function to reverse the models array upon completion. Also I held off triggering the 'sort' event until after the reverse has been completed.

        sort : function(options){
    
            options = options || {};
    
            Backbone.Collection.prototype.sort.call(this, {silent:true});
            this.models.reverse();
    
            if (!options.silent){
                this.trigger('sort', this, options);
            }
    
            return this;
        },
    
    0 讨论(0)
  • 2020-12-02 06:13

    My solution was to reverse results after sort.

    To prevent double rendering first sort with silent, then trigger 'reset'.

    collections.sort({silent:true})
    collections.models = collections.models.reverse();
    collections.trigger('reset', collections, {});
    
    0 讨论(0)
  • 2020-12-02 06:13

    Here's a quick and easy way to reverse-sort a collection's models using UnderscoreJS

     var reverseCollection = _.sortBy(this.models, function(model) {
       return self.indexOf(model) * -1;
     });

    0 讨论(0)
  • 2020-12-02 06:26

    Recently ran into this issue and just decided to add an rsort method.

        Collection = Backbone.Collection.extend({
                comparator:function(a, b){
                    return a>b;
                },
                rsort:function(){
                    var comparator = this.comparator;
    
                    this.comparator = function(){
                        return -comparator.apply(this, arguments);
                    }
                    this.sort();
    
                    this.comparator = comparator;
    
                }
        });
    

    Hopefully someone will find this useful

    0 讨论(0)
提交回复
热议问题