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
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!');
}
})
对于测试套件,我获取了latest views tests from GitHub,并将出现的Backbone.View替换为RegularView。然后,测试使用RegularView和RegularView.extend()的结果来确保两者都执行了它们应该执行的操作。
3条答案
按热度按时间bwitn5fc1#
继承视图最简单的方法是做其他人已经在评论中建议的事情:
但是正如你在评论中提到的,如果你在Pannel中有一个initialize方法,那么如果你在PannelAdvanced中也有一个initialize方法,它就不会被调用,所以你必须显式调用Pannel的initialize方法:
如果你有很多继承自Pannel的视图,那么你必须记住从所有视图中调用Pannel的initialize方法。更糟糕的是,如果Pannel现在没有initialize方法,但你选择在将来添加它,那么你以后就需要访问所有继承的类并确保它们调用Pannel的initialize。这是定义Pannel的另一种方法,这样您继承的视图就不需要调用Pannel的initialize方法:
gopyfrb32#
这也是我喜欢使用Coffeescript的原因之一。继承之类的东西要好得多。为了背上@JohnnyO的正确答案,我可以在Coffeescript中说同样的话:
q43xntqr3#
再进一步说:
我喜欢@JohnnyO的方法,但我想确认生成的视图仍然能够完成它应该做的所有事情。考虑到他的方法,我不怀疑会有任何问题,但我想更确定一点。
因此,我花了一分钟的时间,将Backbone.js Views test suite修改为JohnnyO提出的多重继承技术。
您可以在http://jsfiddle.net/dimadima/nPWuG/下运行结果。所有测试均通过。
我的基础视图和扩展视图:
对于测试套件,我获取了latest views tests from GitHub,并将出现的
Backbone.View
替换为RegularView
。然后,测试使用RegularView
和RegularView.extend()
的结果来确保两者都执行了它们应该执行的操作。