3

Need to call .delegateEvents() on all child views inside a parent "collection" view in order to re-delegate events after having removed the parent view from the page and then put it back on.

I can see two ways of doing this, both of which don't sound quite right to me in terms of proper practices:

  • Whenever addOne() is called in the parent view, save the child view that was just created to a list. When the events need to be re-delegated later on when the view is added back onto the page. Use the array to scroll back through that list and call .delegateEvents() on each child view item. The problem with this approach, is the creating of a separate array to hold everything inside the view when the view already has a Backbone-sanctioned way to influence it's child views through this.collection.each()
  • Use the built in View.collection.each() inside the view to scroll through each child model. Trigger an event on each model that causes its corresponding view to call .delegateEvents() on itself. The problem with this approach is that a purely view-oriented action is being routed through the models.

Are either of these approaches any good or is there a better way that I should be doing this?

Thanks so much!

Chris Dutrow
  • 48,402
  • 65
  • 188
  • 258
  • 1
    We're currently struggling with the same problem and are looking into [Marionette](https://github.com/derickbailey/backbone.marionette) to see how this issue is solved there. Derick has a special `CollectionView` which supposedly handles these things. – Torsten Walter Aug 01 '12 at 21:22
  • @TorstenWalter - Just took a few hours and read over Marionette. Did you guys decide to go with it or are than any potential issues? – Chris Dutrow Aug 02 '12 at 12:51
  • 1
    Since we are just started to transit one project and have to touch all the view stuff anyway, implementing Marionette is probably the easiest solution for us in the long run. Currently we have your first solution implemented and update the view collection on `reset`, `remove` and `destroy`. – Torsten Walter Aug 02 '12 at 16:09

2 Answers2

1

Go for the first one. You want to keep a reference to a CollectionView's child views anyway, for proper removal and reinitialization. The problem with the latter pattern is if the model is represented by several collection views, all of those collection views will be triggered unnecessarily.

Jens Alm
  • 3,027
  • 4
  • 22
  • 24
1

You may be able to avoid the whole problem by changing how you remove the list view.

If you call the jQuery.remove() function (or the Backbone.View.remove() function, which is the same thing) it undelegates all the events to avoid memory leaks. But if you think you're going to be adding the view back to the page later, you can use jQuery.detach() to remove the element from the DOM without undelegating all the events. Then you don't need to re-delegate them later, you can just attach the element to the DOM and it's ready to go. I believe it's also a bit faster.

For example, I use the following functions in some of my list views:

detach : function(){
  this.$el.detach();
},

attach : function(newParentEl){
  this.$el.appendTo(newParentEl);
}
Brian Reischl
  • 7,216
  • 2
  • 35
  • 46