What I have is the following:
Views.Parent = Backbone.View.extend( {
template: "parent",
initialize: function( ) {
this.render( );
},
beforeRender: function( ) {
this.setView( ".foo", new Views.Child( {
model: this.model
} );
},
afterRender: function( ) {
this.$el.html( Handlebars.compile( this.$el.html( ) ).call( this, this.model.attributes ) );
var foo = this.getView( ".foo" );
foo.delegateEvents( );
}
} );
Views.Child = Backbone.View.extend( {
template: "child",
events: {
"click input": "inputClick"
},
initialize: function( ) {
this.listenTo( this.model, "change", this.render );
},
inputClick: function( ) {
console.info( "Input Clicked" );
},
afterRender: function( ) {
this.$el.html( Handlebars.compile( this.$el.html( ) ).call( this, this.model.attributes ) );
var foo = this.getView( ".foo" );
foo.delegateEvents( );
}
} );
The events in Views.Child
aren't firing. The view is definitely found and foo.events returns the correct events. I've tried multiple ways of inserting my sub-view, delegateEvents just isn't doing it.
Has anybody else run in to this and can offer any insight?
I should mention I'm using both the events property and this.listenTo in the sub-view. None of them are being fired.
Edit: The parent is being added to another view as such:
this.$el.append( parentView.$el );
Where parentView
is an instantiated object of Views.Parent
.
When you're calling this.$el.html
in afterRender
, you are overwriting the view current HTML (and every bound events/child view). As so, you're removing the child view you set in beforeRender
.
That's why you got no event firing up.
I'd like to provide more insight as to how you should organize your code... But I can't understand what you're trying to do in afterRender
, this make no sense at all. Compile all your template code inside the fetch
and render
configurations options, not in afterRender
.
A quick note:
beforeRender
: where you set child views
afterRender
: where you bind events or startup jQuery plugins, etc. You should not be touching the DOM here.