2011-06-06 76 views
7

this`分辨率我有一個使用視圖繼承的情況下,我的代碼看起來基本上是這樣的:Backbone.js的瀏覽繼承。 `在父母

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(){ 
     ... 
    } 
}); 

更新:感動this.events擴展構造。

我的子視圖中有someFunc,並在父視圖中的某些業務功能,如果它存在,它應該調用該函數。如果this正確設置爲childView,然後this.someFunc應該存在。但是,這不是我所經歷的行爲。

initialize函數(在父類中)中,this確實設置爲子視圖。然而,當some event大火之後,business函數調用this設置爲parentView

回答

9

您是否嘗試過在構造函數中擴展this.events而不是在初始化函數中?如果你在初始化時這樣做,你太晚了; business函數的事件代理已經在構造函數中設置,並指向parentView(請參閱Backbone.View構造函數中的this.delegateEvents();調用)。

更新與工作示例:

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'. 
+0

好,很酷。你能告訴我parentView.prototype.initialize和parentView.constructor.initialize之間的區別嗎? – idbentley 2011-06-07 16:28:52

+0

我更新了我的問題:即使使用這種技術也存在同樣的問題。 'parentView.constructor.initialize'未定義。 – idbentley 2011-06-07 16:59:33

+0

我也試過:'parentView.prototype.constructor',沒有任何運氣。 – idbentley 2011-06-07 18:03:28

0

可以通過添加此行對孩子的initialize方法解決這個問題:

_.bind(this.business, this) 

希望有人能指出基本的機制更好的描述比我可以提供,但我會給它一個鏡頭:

什麼情況是,該方法將使用它,除非另行告知所定義的範圍的範圍內。 initialize是說,當你調用parentView.prototype.initialize.apply(this)因爲你傳入childView與this參照適用的方法來使用孩子的情況下。

如上所述,您可以使用underscore.js bind方法將業務方法綁定到子項的上下文。

+0

權,但是這也是'_.bindAll'功能做什麼。通過在沒有任何額外參數的情況下使用它,它應該綁定到對象中的所有函數。不幸的是,這也不起作用。 – idbentley 2011-06-06 21:04:22

+0

哦,對了,我說,你說得對。不確定:( – c3rin 2011-06-06 22:08:17

2

其實,我不知道這是否能解決你的問題,但我通常會這樣做:this.constructor.__super__.initialize.apply(this, arguments);,工作就像一個魅力。我的解決方案是完全錯誤的。這裏的原因:

var Model1 = Backbone.Model.extend({ 
    method: function() { 
    // does somehting cool with `this` 
    } 
}); 

var Model2 = Model1.extend({ 
    method: function() { 
    this.constructor.__super__.method.call(this); 
    } 
}); 

var Model3 = Model2.extend({ 
    method: function() { 
    this.constructor.__super__.method.call(this); 
    } 
}); 

var tester = new Model3(); 

// Boom! Say hallo to my little stack-overflowing recursive __super__ call! 
tester.method(); 

Model2::methodthis.constructor.__super__的調用將解析(擊鼓)Model2::method

總是使用ExplicitClassName.__super__.methodName.call(this, arg1, arg2 /*...*/)或Coffee-script的super

+0

我喜歡用__super__代替硬編碼父類名稱 – 2012-07-09 23:29:57