Inheritance Backbone.js视图继承
我有一个名为Inheritance Backbone.js视图继承,inheritance,backbone.js,Inheritance,Backbone.js,我有一个名为Pannel的视图,它只是一个带有关闭按钮的背景。我想将该视图扩展到一个名为PannelAdvanced的视图。我将如何使用backbone.js实现这一点 现在所有的例子都有Backbone.View.Extend,但是那些只是扩展Backbone.View;我想扩展我的PannelView继承视图的最简单方法是执行其他人在评论中已经建议的操作: var Pannel = Backbone.View.extend({ }); var PannelAdvanced = Pannel
Pannel
的视图,它只是一个带有关闭按钮的背景。我想将该视图扩展到一个名为PannelAdvanced
的视图。我将如何使用backbone.js实现这一点
现在所有的例子都有
Backbone.View.Extend
,但是那些只是扩展Backbone.View
;我想扩展我的PannelView
继承视图的最简单方法是执行其他人在评论中已经建议的操作:
var Pannel = Backbone.View.extend({
});
var PannelAdvanced = Pannel.extend({
});
但正如您在评论中所指出的,如果您在Pannel中有一个initialize方法,那么如果您在PanneLadAdvanced中也有一个initialize方法,则不会调用它,因此您必须显式调用Pannel的initialize方法:
var Pannel = Backbone.View.extend({
initialize: function(options){
console.log('Pannel initialized');
this.foo = 'bar';
}
});
var PannelAdvanced = Pannel.extend({
initialize: function(options){
Pannel.prototype.initialize.apply(this, [options])
console.log('PannelAdvanced initialized');
console.log(this.foo); // Log: bar
}
});
这有点难看,因为如果您有很多从Pannel继承的视图,那么您必须记住从所有视图调用Pannel的initialize。更糟糕的是,如果Pannel现在没有initialize方法,但您选择在将来添加它,那么您需要在将来转到所有继承的类,并确保它们调用Pannel的initialize。因此,这里有另一种定义Pannel的方法,这样继承的视图就不需要调用Pannel的initialize方法:
var Pannel = function (options) {
// put all of Panel's initialization code here
console.log('Pannel initialized');
this.foo = 'bar';
Backbone.View.apply(this, [options]);
};
_.extend(Pannel.prototype, Backbone.View.prototype, {
// put all of Panel's methods here. For example:
sayHi: function () {
console.log('hello from Pannel');
}
});
Pannel.extend = Backbone.View.extend;
// other classes inherit from Panel like this:
var PannelAdvanced = Pannel.extend({
initialize: function (options) {
console.log('PannelAdvanced initialized');
console.log(this.foo);
}
});
var pannelAdvanced = new PannelAdvanced(); //Log: Pannel initialized, PannelAdvanced initialized, bar
pannelAdvanced.sayHi(); // Log: hello from Pannel
这是我如此喜欢使用Coffeescript的原因之一。像继承这样的事情好多了。为了支持@JohnnyO的正确答案,我可以在Coffeescript中说同样的话:
class Panel extends Backbone.View
initialize: ->
console.log 'Panel initialized'
@foo = 'bar'
class PanelAdvanced extends Panel
initialize: ->
super
console.log 'PanelAdvanced initialized'
console.log @foo
要更进一步,请执行以下操作: 我喜欢@JohnnyO的方法,但想确认结果视图仍然能够完成它应该做的一切。考虑到他的方法,我不怀疑会有任何问题,但我想更确定一点 因此,我花了一分钟的时间,使之适应了@johnyo提出的多重继承技术 您可以在运行结果所有测试都通过。 我的基本视图和扩展视图:
var RegularView = function (options) {
// All of this code is common to both a `RegularView` and `SuperView`
// being constructed.
this.color = options && (options.color || 'Green');
// If execution arrives here from the construction of
// a `SuperView`, `Backbone.View` will call `initialize`
// that belongs to `SuperView`. This happens because here
// `this` is `SuperView`, and `Backbone.View`, applied with
// the current `this` calls `this.initialize.apply(this, arguments)`
Backbone.View.apply(this, arguments)
};
RegularView.extend = Backbone.View.extend;
_.extend(RegularView.prototype, Backbone.View.prototype, {
// Called if a `RegularView` is constructed`,
// Not called if a `SuperView` is constructed.
initialize: function () {
console.log('RegularView initialized.');
},
say_hi: function() {
console.log('Regular hi!');
}
});
var SuperView = RegularView.extend({
// Called if a `SuperView` is constructed`,
// Not called if a `RegularView` is constructed.
initialize: function(options) {
console.log('SuperView initialized.')
},
say_hi: function() {
console.log('Super hi!');
}
})
对于测试套件,我抓取并将出现的
Backbone.View
替换为RegularView
。然后测试使用RegularView
和RegularView.extend()
的结果来确保两者都做了它们应该做的事情。它的工作方式完全相同-Panel.extend({…})
我有Panel=Backbone.View.extend(),然后我有advancedPanel=Panel.extend()但是,当我在advancedPanel内部的面板初始化方法中为一个变量做控制台日志时,它显示为未定义。我可以在不先实例化面板的情况下调用Panel.extend()吗?我将其转换为javascript,只是想看看我是否能将其写入:super
变成Panel.prototype.initialize.apply(这是参数)代码>我在传递参数时无法使其工作。它们不会出现在中。选项@Maletor:您使用的是什么版本的主干网?它是在0.9.9或类似的版本中添加的@NicoGranelli您的代码不是咖啡脚本的1:1翻译。请从CoffeeScript弹出窗口中选择Convert to Javascript。此模式不适用于在子级和父级中声明的事件,因为在调用var PannelAdvanced=Pannel.extend({events:{…}})
时,dict中父级的事件键被子级的事件键覆盖。您可以在父级中声明parentsEvents键,然后在父级构造函数中调用this.delgateEvents(this.parentEvents)
,但由于在主干中,它们将由于子视图而再次被删除。实际上,您可以这样做。在childEvents键或其他任何键中声明子事件,然后在父级中声明一个events
函数,使用:return\u0.extend({“click.parentClass”:“parentFunction”},this.childEvents)
使用\u super
不是最佳选择。我同意。最好使用原型。我更新了我的答案以反映这一点。