Answer the question
In order to leave comments, you need to log in
Sorting/filtering in Backbone?
Let's imagine that you populated a collection with models and rendered it. Everything is displayed on the page, and the user wanted to display all the records in reverse order (or, let's say, only those that contain some keyword)
What is the best way to deal with this situation?
The option to sort / filter the collection comes to mind and then everything is back in the DOM.
Who does what?
Answer the question
In order to leave comments, you need to log in
All of you suggested correctly. Most of the time, that's the only way to do it. The main thing in the DOM is to insert the entire rendered collection at once, and not one view at a time. And do not forget to clean up after yourself if there are any dashing bindings.
I believe that completely re-rendering a collection when sorting is generally a step back from the MVC ideology. You only need to re-render what has changed.
When sorting or filtering, we can use smart updating of collections from the server. It will trigger the appropriate add, remove, change events. I add 4 "classes" to any list interface, for example: CommentListViewClass, CommentItemViewClass, CommentCollectionClass, CommentModelClass.
We pass CommentCollection to CommentListView, and call CommentCollection.fetch()
Actually, all the salt is done in CommentListView, I will fetch it.
var CommentsListViewClass = Backbone.View.extend({
initialize: function(options){
this.templateData = options && options.templateData || {};
this.listenTo(this.collection, "add", this.renderItem);
this.listenTo(this.collection, "add remove sync", this.renderUpdate);
this.listenTo(this.collection, "sync", this.resortItems);
this.itemViews = [];
},
render: function(){
this.$el.empty();
},
renderUpdate: function(){
$('.comments_count').html(this.collection.length);
},
resortItems: function(){
this.collection.each(_.bind(function(m,i){
var viewEl = this.$("."+m.cid);
this.placeItem(viewEl, m);
}, this));
},
placeItem: function(itemEl, model){
var index = _.indexOf(this.collection.models, model);
//console.log(index, itemEl,model);
if(index == 0){
console.log("#"+ index ,model.id, 'ontop');
this.$el.prepend(itemEl);
} else {
var pIndex = index-1;
var cid = this.collection.models[pIndex].cid;
this.$el.find('.'+cid).after(itemEl);
console.log("#"+ index, model.id, "after " + this.collection.models[pIndex].id );
}
},
renderItem: function(model, collection, options){
var item = new CommentsItemViewClass({
model: model,
templateData: this.templateData
});
var itemEl = item.render();
this.placeItem(itemEl, model);
}
});
var item = new CommentsItemViewClass({
model: model,
templateData: this.templateData
});
//получим DOM-элемент вида
var itemEl = item.render();
var index = _.indexOf(this.collection.models, model);
//console.log(index, itemEl,model);
if(index == 0){
this.$el.prepend(itemEl);
} else {
var pIndex = index-1;
//cid предыдущей модели
var cid = this.collection.models[pIndex].cid;
this.$el.find('.'+cid).after(itemEl);
}
this.collection.each(_.bind(function(m,i){
var viewEl = this.$("."+m.cid);
this.placeItem(viewEl, m);
}, this));
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question