Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js: Update model, re-sort and re-render models collection

In my app I have a socket.io connection that is listening to the backend and getting updates to models held by the clients browser (which retrieves the model by id and calls set on the model attribute).

I'd like the collection to be sorted, then re-rendered as a whole in order to reflect any new ordering on the models as a result of the set (most examples seem to be around individual views being re-rendered). What's a method of achieving this?

NB I've got a backbone.js layout lifted pretty verbatim from the example todo app (this is the first backbone app).

like image 653
mrmagooey Avatar asked Apr 22 '12 03:04

mrmagooey


People also ask

Which of the following is the correct syntax for creating backbone collection with model model?

The Backbone. js collection models specify the array or models which are created inside of a collection. Syntax: collection.

What is the significance of edge version of BackboneJS?

js provides framework to web apps by giving demos with value binding and custom events and allocations with an API of enumerable functions and views with reportive event handling and links all to your existing API over an interface.


1 Answers

You can achieve what you want by providing a comparator method for your collection.

Example:

ModelCollection = Backbone.Collection.extend({
    comparator: function(a, b) {
        if ( a.get("name") > b.get("name") ) return 1;
        if ( a.get("name") < b.get("name") ) return -1;
        if ( a.get("name") === b.get("name") ) return 0;
    },

    initialize: function() {
        this.on('change:name', function() { this.sort() }, this);
    }
});

The comparator in this example will cause your collection to be sorted in ascending order by the name attribute of the models inside.

Note that your collection won't be sorted automatically when changing attribute(s) of any of its models. By default, sorting happens only when creating new models and adding them to the collection; but the comparator will be used by the collection.sort method.

The code above takes advantage of this by setting an event listener that simply re-sorts the collection on any changes to the name attributes of its models.

To complete the picture, we set up an appropriate event listener in the View associated with the collection to make sure it re-renders on any changes:

CollectionView = Backbone.View.extend({
    initialize: function() {
        this.collection = new ModelCollection();
        this.collection.on('all', function() { this.render() }, this);
    },

    render: function() {
        this.$el.html(this.collection.toJSON());
    }
});

That's it :)


Relevant excerpt from the Backbone documentation:

By default there is no comparator for a collection. If you define a comparator, it will be used to maintain the collection in sorted order. This means that as models are added, they are inserted at the correct index in collection.models. A comparator can be defined as a sortBy (pass a function that takes a single argument), as a sort (pass a comparator function that expects two arguments), or as a string indicating the attribute to sort by. [...] Collections with a comparator will not automatically re-sort if you later change model attributes, so you may wish to call sort after changing model attributes that would affect the order.

like image 74
drinchev Avatar answered Jan 04 '23 10:01

drinchev