Reputation: 146064
I have to display the same collection of backbone models in 2 different places on the same page (once in the navigation, once in the main area), and I need to keep the models in the collections in sync but allow each collection to be sorted differently. The nav is always alphabetical ascending but the sorting in the main content area is configurable by the user. What's the best way to do this? Should I have 2 different collections and event bindings to try to make sure their models are always identical (using the add/remove/reset events)? Should I have just 1 collection and change it's sort order on the fly as needed?
Upvotes: 3
Views: 1622
Reputation: 33344
I usually consider that the collections should not be altered to represent a transient reordering, so :
For example,
var C = Backbone.Collection.extend({
comparator: function (model) {
return model.get('name');
},
toJSON_sorted: function (reversed) {
var models = this.toJSON();
return (!reversed) ? models : models.reverse();
}
});
var V = Backbone.View.extend({
initialize: function () {
this.collection.on('reset', this.render, this);
this.collection.on('change', this.render, this);
this.collection.on('add', this.render, this);
this.collection.on('delete', this.render, this);
}
});
var NavView = V.extend({
render : function () {
console.log(this.collection.toJSON());
}
});
var MainView = V.extend({
render : function () {
var data = this.collection.toJSON_sorted(this.reversed);
console.log(data);
}
});
Calling these definitions
var c=new C();
var v1 = new NavView({collection:c});
var v2 = new MainView({collection:c});
v2.reversed=true;
c.reset([
{name:'Z'},
{name:'A'},
{name:'E'}
]);
provides the views with the models in the expected order and lets you change the sort direction at will. You could also tailor toJSON_sorted
to handle sorting by other fields.
A Fiddle to play with http://jsfiddle.net/nikoshr/Yu8y8/
Upvotes: 3
Reputation: 454
All you have to do is change the comparator function. You have have methods on your collection to do this but the basic idea is
var mycollection = new Backbone.Collection();
mycollection.comparator = function(item) { return item.get('blah') }
Upvotes: 0
Reputation: 8581
If the collections contain exactly the same thing, I think keeping 1 collection and utilizing that for both displays is the most tidy. Just call the sort function before you render whatever visual component you want.
Upvotes: 1