Backbone: event lost in re-render
backbone-events, backbone.js, javascript
Solution
When you do this:
this.$el.html( this.subView.render().el );
You're effectively saying this:
this.$el.empty();
this.$el.append( this.subView.render().el );
and `empty` kills the events on everything inside `this.$el`:
To avoid memory leaks, jQuery removes other constructs such as data and event handlers from the child elements before removing the elements themselves.
So you lose the `delegate` call that binds events on `this.subView` and the `SubView#render` won't rebind them.
You need to slip a `this.subView.delegateEvents()` call into `this.$el.html()` but you need it to happen after the `empty()`. You could do it like this:
render: function(){
console.log( "Composer.render" );
this.$el.empty();
this.subView.delegateEvents();
this.$el.append( this.subView.render().el );
return this;
}
Demo: http://jsfiddle.net/ambiguous/57maA/1/
Or like this:
render: function(){
console.log( "Composer.render" );
this.$el.html( this.subView.render().el );
this.subView.delegateEvents();
return this;
}
Demo: http://jsfiddle.net/ambiguous/4qrRa/
Or you could `remove` and re-create the `this.subView` when rendering and sidestep the problem that way (but this might cause other problems...).
Problem
I have super-View who is in charge of rendering sub-Views. When I re-render the super-View all the events in the sub-Views are lost. This is an example: ``` var SubView = Backbone.View.extend({ events: { "click": "click" }, click: function(){ console.log( "click!" ); }, render: function(){ this.$el.html( "click me" ); return this; } }); var Composer = Backbone.View.extend({ initialize: function(){ this.subView = new SubView(); }, render: function(){ this.$el.html( this.subView.render().el ); } }); var composer = new Composer({el: $('#composer')}); composer.render(); ``` When I click in the click me div the event is triggered. If I execute `composer.render()` again everything looks pretty the same but the click event is not triggered any more. Check the working jsFiddle.