Stevo
Stevo

Reputation: 2639

Why is this backbone view not rendering correctly?

I've got a couple of views in backbone.js and I want want to be a child of the other. So I've created the following code.

var app = app || {} ;

app.ProjectCardView = Backbone.View.extend({

    el: $('.list'),

    template: _.template( $("#tpl-project-card-summary").html() ),


    initialize: function() {
        this.render();
    },

    render: function() {
        return this.$el.html( this.template() );

    }

});


app.DashboardView = Backbone.View.extend({

    el: $('.contentwrap'),

    template: _.template( $("#tpl-dashboard").html() ),

    initialize: function() {
        this.render();
        this.addProjects();
    },

    render: function() {
        //console.log(this.template());
         this.$el.html( this.template() );

    },

    addProjects: function() {
        var pcv = new app.ProjectCardView();    
    }



});

app.dash = new app.DashboardView;

The DashboardView renders perfectly, but when I create the ProjectCardView, the view doesn't seem to initialise so the template is empty and el is not set. If I set el in the initialize function, then $el is still not set. I just can't see what I'm doing wrong.

EDIT: looks like I found the issue; $('.list') is an element introduced by the first view, as such, it's not rendered by the time the second view is trying to find it - even though the first view has rendered in the DOM.

So how do I fix that?

Upvotes: 1

Views: 566

Answers (1)

nemesv
nemesv

Reputation: 139758

If you specify your el as a jQuery selector $('.list') you should know that it will be executed when your Backbone.View.extend is executed. So if your element is not in the DOM by that time your selector won't work.

So you need to specify the el when it is in the DOM. So in your case you can write:

addProjects: function() {
    var pcv = new app.ProjectCardView({ el: $('.list') });    
}

Or you can use the Backbone feature that you can specify the el as a string istead of the jQuery selector:

app.ProjectCardView = Backbone.View.extend({    
    el: '.list',
    //...
}

Upvotes: 5

Related Questions