Correct way to insert a view with Backbone.js

5.2k views Asked by At

I have a simple backbone.js app. I want to render a view into the DOM of the HTML page, this view is a detail view for a model. My HTML page already has the DIV element that I want to render the view into. If I try to render my view like this:

detailView = new RulesPanelView({model : @model})
$("#detail").html(detailView.render().el)

It fails and I get [Object HTMLDivElement] inserted into the DOM, not my rendered HTML.

This is the only way I can get it to work and it seems like a hack:

$("#detail").html('')
detailView = new RulesPanelView({model : @model})
$("#detail").append(detailView.render().el)

Having to empty the HTML of the DIV before rendering so I don't get multiple views rendered inside #detail which is what would happend with append.

Also aren't I creating way too many views this way, just seems cleaner to replace the HTML as in the first code segment?

What is the correct way to render this view?

2

There are 2 answers

5
Arthur Debert On

What you want is to pass the already inserted DOM node to the view as a 'el' option to the constructor:

new RulesPanelView({el: $("#detail")});

This way, it won't render again. You still need to make sure your view's 'render' method will be able to render a correct view from an updated model, though.

The backbone documentation mentions this as a good way to avoid rendering too much stuff at once.

1
meirish On

I actually append in the render method of the view. This doesn't work if you want to re-render when models change - but for that I've added a refresh method that render actually calls before appending. I then bind the refresh to the model change (if I need that). So in my View, I do this:

render: function(){
    var markup = this.refresh();
    $(markup).appendTo('#some-selector');
    return this;
}, 
refresh: function(){
    return $(this.el).html($.mustache(this.template, this.model.toJSON()));
},

Not sure if that's the "best", but I think it works pretty well. I've also seen where you have a collection bound to a view that loops through all of the models and renders "sub-views" of the collection view - this provides a nicer programmatic approach than hard-coding where you're going to append.