Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js view inheritance. `this` resolution in parent

I have a case that uses view inheritance, and my code looks essentially like:

parentView = Backbone.View.extend({
    events: {
        "some event": "business"
    },
    initialize: function(){
        _.bindAll(this);
    },
    business: function(e){
        ...
        this.someFunc && this.someFunc();
        ...
     }
});

childView = parentView.extend({
    events: {
        ...
    },
    constructor: function(){
       this.events = _.extend( {}, parentView.prototype.events, this.events );
       parentView.prototype.initialize.apply( this );
    },
    initialize: function(){
       _.bindAll(this);
    },
    someFunc: function(){
       ...
    }
});

Update: Moved this.events extension to the constructor.

My child view has someFunc in it, and during some business function in the parent view, it should call that function if it exists. If this is properly set to the childView, then this.someFunc should exist. This, however, is not the behaviour that I am experiencing.

During the initialize function (in the parent), this is indeed set to the child view. However, when some event fires, the business function is called with this set to parentView.

like image 978
idbentley Avatar asked Jun 06 '11 20:06

idbentley


1 Answers

Have you tried extending this.events in the constructor, instead of in the initialize function? If you do this in initialize, you're too late; event delegation for the business function has already been setup in the constructor, and will point to parentView (see the call to this.delegateEvents(); in Backbone.View's constructor).

Updated with a working example:

ParentView = Backbone.View.extend({
    name: 'ParentView',
    events: {
        "event": "business"
    },
    business: function(e){
        this.someFunc && this.someFunc();
    }
});

ChildView = ParentView.extend({
    name: 'ChildView',
    events: {
    },
    constructor: function(){
       this.events = _.extend( {}, ParentView.prototype.events, this.events );
       console.debug( this.events );
       ParentView.prototype.constructor.apply( this, arguments );
    },
    someFunc: function(){
        console.debug('someFunc; this.name=%s', this.name);
    }
});

child = new ChildView();
$( child.el ).trigger('event');
// logs 'this' in 'someFunc'; the name is 'ChildView'.
like image 148
Paul Avatar answered Sep 21 '22 09:09

Paul