0

My question most likely requires a very simple answer, which, nevertheless, I was not able to easily find.

A Backbone application I am working on has several views. When defining the different views, I use _.bindAll in the initialize function to connect the "this" view object with the view's render function. For example:

DiscussedItemView = Backbone.View.extend({
    ...
        initialize: function() {
            _.bindAll(this, "render");
        },


        render: function() {    

            this.$el.attr('id', 'li-meeting-task-' + this.model.getId());

            this.$el.html(JST['tasks_sandbox/agenda_task_item']({ 
                taskName    : this.model.getName(),
                taskId      : this.model.getId()
            }));

            return this;
        },
    ...
});

To create a new instance of the DiscussedItemView, I do the following:

...
        var discussion_agenda_row = new DiscussedItemView({model: task});
        discussion_agenda_row.render();
        this.$( '#meeting-items-list' ).append(discussion_agenda_row.$el); 
...

The code works fine. Still, I do not understand why there is a need for the explicit use of the render() function on discussion_agenda_row. I thought that the initialization of a new DiscussedItemView instance would automatically call the render function, but if I remove the discussion_agenda_row.render(); row, the HTML will not be displayed. Where am I mistaken?

Thank you, Alexandra

AndraD
  • 2,830
  • 6
  • 38
  • 48

2 Answers2

2

No, render is not automatically called by initialize. Other components in your application such as your router or another view will tell your view when to render itself.

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
1

Views respond to changes in the model. In your code, you're not making a change to the model, so the view is not responding. You also haven't set the view as a listener to model changes. What you could do in your initialize is something like this:

initialize : function() {
    //this will tell the view to render when the model 
    //triggers a "change" event
    this.model.on("change", this.render, this);

    //this will make the model throw the change event
    //and since the view is listening to "change," render will be invoked.
    this.model.fetch();
}

All that said, if you're not doing any fetching and the data is just there in your model, you'll still have to explicitly call view.render(). In any case, for good MVC, I'd still make the view listen to changes in the model so it will properly update itself in response.

Brendan Delumpa
  • 1,155
  • 1
  • 6
  • 11
  • Thank you - your answer was easy to follow. Now I understand that, if you use in the initialize function _.bindAll(this, "render"), you can omit the "this" parameter in this.model.on(), and only write this.model.on("change", this.render), since the context is already preserved. – AndraD May 21 '12 at 20:18
  • Yes, you could definitely do that, but I'd rather specify the context within the "on" as opposed to making two calls. When you do that, you eliminate the need to call bindAll. – Brendan Delumpa May 21 '12 at 20:43