2011-06-06 78 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