Backbone.js: call render () from an Initialize: function view

I want my view to appear when it is first created, so I call this.render(); in the initialize: function, for example, (remote code):

 var MyView = Backbone.View.extend({ el: $("#mydiv"), initialize: function() { this.render(); } ... 

In the render: function render: I then iterate over the child collection and add the rendered views of each child:

 render: function() { this.model.somecollection.forEach(function(c) { var view = new ChildView({ model: c }); this.el.append(view.render().el); //***** }); return this; }, 

The problem I ran into is that the link to this in the rendering function (marked with asterisks) is set to window , not to the MyView object and causes an error.

I assume that I am this.render(); render incorrectly (currently this.render(); ). How should I do this to maintain this context?

+4
source share
5 answers

Save this outside the for loop.

 var that = this; 

this not _.each() inside the loop if you use _.each() .

+6
source

In Javascript, whenever you enter a new function context, the value of this is most likely changed. All you have to do is save the this value before entering the function:

 render: function() { var self = this; this.model.somecollection.forEach(function(c) { var view = new ChildView({ model: c }); self.el.append(view.render().el); //***** }); return this; }, 
+5
source

that's how we use it

thus, the render is still called upon initialization.

 ContactView = Backbone.View.extend({ initialize: function(){ this.render(); }, render: function(){ // we use underscsore templating, this just gives a chunk of html var template = _.template( $("#search_template").html(), {} ); // and we load that template html into the Backbone "el" this.el.html( template ); } }); 

we give 'el' a look when we create the view, and the render function inserts the html into this element.

 var contact_view = new ContactView({ el: $("#contact-list") }); 
+3
source

In the context of an anonymous function, this refers to a global scope. You need to explicitly save this if you want to use the code the way you wrote it. Assuming you have jquery on your page: you can use the $ .proxy function:

 this.model.somecollection.forEach($.proxy(function(c) {    var view = new ChildView({ model: c });   this.el.append(view.render().el); },this)); 

Alternatively, underscore has the _.bind function, which works in a similar way. Also, if you define a local variable and assign it outside an anonymous function, you can use it instead of this function anonymous.

+3
source

If somecollection is a Backbone.Collection, you should be able to say:

this.model.somecollection.each(..., this);

The last parameter is the context to be used inside the function.

+3
source

All Articles