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).
The Backbone. js collection models specify the array or models which are created inside of a collection. Syntax: collection.
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.
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 change
s 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 acomparator
, 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 incollection.models
. A comparator can be defined as asortBy
(pass a function that takes a single argument), as asort
(pass a comparator function that expects two arguments), or as a string indicating the attribute to sort by. [...] Collections with acomparator
will not automatically re-sort if you later change model attributes, so you may wish to callsort
after changing model attributes that would affect the order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With