Bulk replacements are easier and more efficient using reset
:
reset
collection.reset([models], [options])
Adding and removing models one at a time is all well and good, but sometimes you have so many models to change that you'd rather just update the collection in bulk. Use reset to replace a collection with a new list of models (or attribute hashes), triggering a single
"reset"
event at the end. Returns the newly-set models. For convenience, within a"reset"
event, the list of any previous models is available asoptions.previousModels
.
So instead of using set
to merge the changes and generate a bunch of 'add'
and 'remove'
events, using reset
and listen for 'reset'
event:
// In the view's `initialize`...
this.listenTo(this.collection, 'reset', this.render);
and then render
can redraw the whole thing and you'd say:
suggestionsView.collection.reset(this.getSuggestions(query))
// ------------------------^^
to refresh things.
Some clarification from the comments: Models don't generate 'add'
events, only collections trigger those. Models trigger 'change'
events when their properties change, collections trigger 'add'
and 'remove'
events when models are added and removed (respectively) from them; collections can also trigger 'change'
events because they forward all the events from their enclosed models:
Any event that is triggered on a model in a collection will also be triggered on the collection directly, for convenience.
So if you want to use Collection#set
then you'd want three handlers in your view:
this.listenTo(this.collection, 'add', ...)
: A new model has been added to the collection so render it.this.listenTo(this.collection, 'remove', ...)
: A model has been removed from the collection so remove its part of the view.this.listenTo(this.collection, 'change', ...)
: A model has changed so update its part of the view.
If you're only working with small collections then reset
might be less work. If your collections are larger or the view changes are more expensive then dealing with the three events separately might be best.
In any case, if you're using sub-views, you'll want to maintain a list of them somewhere in the parent view so that you can call remove
on them to make sure things are properly cleaned up. If you're destroying the models when removing them from the collection, you could have the sub-views bind to their model's 'destroy'
events and remove themselves as needed.
The Catalog of Events might be worth a review to see what events are triggered at which times.