Search code examples
backbone.jsbackbone-eventsbackbone-layout-manager

Backbone Layoutmanager delegateEvents on subview not working


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.


Solution

  • 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.