Backbone.js视图inheritance

我有一个叫做Pannel的视图,它只是一个closuresbutton的背景。 我想把这个观点扩展到一个叫做PannelAdvanced视图。 我将如何与backbone.js做到这一点?

现在所有的例子都有Backbone.View.Extend但是只是扩展了Backbone.View ; 我想扩展我的PannelView

inheritance视图最简单的方法就是去做其他人在评论中已经提出的build议:

 var Pannel = Backbone.View.extend({ }); var PannelAdvanced = Pannel.extend({ }); 

但是就像你在注释中注意到的那样,如果你在Pannel中有一个初始化方法,那么如果你在PannelAdvanced中也有一个初始化方法,它将不会被调用,所以你必须明确地调用Pannel的初始化方法:

 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 } }); 

这有点难看,因为如果你有很多从Pannelinheritance的视图,那么你将不得不记得从所有视图中调用Pannel的初始化。 更糟糕的是,如果Pannel现在还没有初始化方法,但是您将来select添加它,那么您将需要继续使用所有inheritance的类,并确保它们调用Pannel的初始化。 所以这里有一个定义Pannel的替代方法,以便你的inheritance视图不需要调用Pannel的初始化方法:

 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的原因之一。 像inheritance这样的东西好得多。 要捎带@ 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的方法,但是想确认一下,由此产生的观点仍然能够做到它应该做的一切。 鉴于他的方法,我没有怀疑会有什么问题,但我想要更确定一些。

所以,我花了一分钟的时间,将Backbone.js Viewstesting套件修改为@JohnnyO提出的多重inheritance技术。

您可以在http://jsfiddle.net/dimadima/nPWuG/上运行结果。; 所有testing通过。

我的基础和扩展视图:

 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!'); } }) 

对于testing套件,我从GitHub抓取了最新的视图testing,并用RegularView取代了Backbone.ViewRegularView 。 testing然后使用RegularViewRegularView.extend()的结果来确保两者都做他们应该做的。