开发者

Backbone.js: calling render() from view's Initialize: function

I want to my view to render itself when it is first created, so I am calling this.render(); in the initialize: function, like this (some code removed):

var MyView = Backbone.View.extend({

    el: $("#mydiv"),

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

In the render: function I'm then looping through a child collection, and appending the rendered views of each child element:

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'm having is that that the reference to this in the render function (marked with asterisks) is set to 开发者_开发问答window rather than the MyView object, and it's causing an error.

I assume I am calling render incorrectly (currently this.render(); ). How should I be doing this so that the this context is preserved?


Save this outside the for loop.

var that = this;

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


In Javascript, whenever you enter a new function context, the value of this has likely changed. All you need to do is store the value of this before you enter 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;
},


this is how we use it here,

this way the render is still invoked when initialized.

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 the 'el' to the view when we create the view, and the render function inserts html into that element.

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


In the context of the anonymous function this refers to the global scope. You need to explicitly preserve this if you wish to use the code in the way you have written. Assuming you have jquery in your page : $.proxy function can be used :

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

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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜