骨干.js 视图继承。父级中的“this”分辨率
Posted
技术标签:
【中文标题】骨干.js 视图继承。父级中的“this”分辨率【英文标题】:backbone.js view inheritance. `this` resolution in parent 【发布时间】:2011-06-06 20:04:50 【问题描述】:我有一个使用视图继承的案例,我的代码看起来基本上是这样的:
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
。
【问题讨论】:
【参考方案1】:您是否尝试过在构造函数中扩展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'.
【讨论】:
好的,很酷。你能告诉我 parentView.prototype.initialize 和 parentView.constructor.initialize 的区别吗? 我更新了我的问题:同样的问题存在,即使使用这种技术。parentView.constructor.initialize
未定义。
我也试过:parentView.prototype.constructor
,没有任何运气。
更新了答案; parentView.constructor.initialize
是一个复制/粘贴错误,我的意思是 parentView.prototype.constructor
当然。为我工作!
不同的是先调用constructor
,实际设置对象;通常,您不必触摸它。 constructor
然后继续设置事件,最后调用 initialize
。【参考方案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::method
中对this.constructor.__super__
的调用将解析为(鼓)Model2::method
。
总是使用ExplicitClassName.__super__.methodName.call(this, arg1, arg2 /*...*/)
或Coffee-script的super
。
【讨论】:
我喜欢使用 super 而不是硬编码父类名【参考方案3】:你可以通过在child的initialize方法中加入这一行来解决这个问题:
_.bind(this.business, this)
希望有人能给你指出比我能提供的更好的底层机制描述,但我会试一试:
除非另有说明,否则该方法将使用它定义的范围的上下文。当您调用 parentView.prototype.initialize.apply(this)
时,initialize
被告知使用子项的上下文,因为您通过对 apply 方法的 this
引用传入 childView。
您可以使用 underscore.js 的 bind
方法将业务方法绑定到孩子的上下文,如上所述。
【讨论】:
对,但这也是_.bindAll
函数的作用。通过在没有任何额外参数的情况下使用它,它应该绑定到对象中的所有函数。不幸的是,这也不起作用。以上是关于骨干.js 视图继承。父级中的“this”分辨率的主要内容,如果未能解决你的问题,请参考以下文章
reactjs checkboxlist组件 - 更新父级中的状态更改