我有一个Backbone.View
的通用子类,它有一个close
事件监听器。
var GenericView = Backbone.View.extend({
events : {
"click .close" : "close"
},
close : function () {
console.log("closing view");
}
});
我想继承这个泛型类并添加一些新事件。但是,下面将覆盖超类(上面)事件对象。 E.g。
var ImplementedView = new GenericView({
// setting this will stop 'close' in Super Class from triggering
events : {
"click .submit" : "submit"
}
});
我应该如何创建子类,在这种情况下ImplementedView
并保留事件?
我找到了一种方法来实现这一点,通过在构造子类时扩展事件对象。但是我需要重新触发this.delegateEvents()
,我猜这不好。任何人都可以对此发表评论吗?
var ImplementedView = new GenericView({
initialize : function (options) {
_.extend(this.events, {
"click .submit" : "submit"
});
// re-attach events
this.delegateEvents();
}
});
答案 0 :(得分:28)
@Nupul是完全正确的:你不是你的GenericView
的子类。
事实上,子类化在这里并不是正确的词,因为JavaScript不进行经典继承。
所以让我们首先尝试理解这里发生的事情:
var GenericView = Backbone.View.extend( propertiesObj, classPropertiesObj )
Backbone.View
是一个构造函数,在使用new
关键字调用时,会为您创建一个新对象。
由于这是JS,所有函数都是函数对象,因此Backbone.View.extend
只是一个挂起Backbone.View
的函数,可以执行以下操作:
GenericView
)来实例化你继承类的对象因此,设置所需原型链的正确方法是:
var ImplementedView = GenericView.extend({
// implementation goes here
});
和NOT:
var ImplementedView = new GenericView({//stuff});
因为这只会创建一个GenericView的新实例。
现在,您仍有问题,因为当您执行以下操作时:
var impl_view = new ImplementedView;
impl_view.events; // This isn't merged with the events you created
// for the GenericView
此时有不同的方法可以获得您想要的结果,这里使用的delegateEvents
类似于您的方式。顺便使用它也不错。
var GenericView = Backbone.View.extend({
genericEvents: { 'click .close': 'close' },
close: function() { console.log('closing view...'); }
});
var ImplView = GenericView.extend({
events: { 'click .submit': 'submit' },
initialize: function(options) {
// done like this so that genericEvents don't overwrite any events
// we've defined here (in case they share the same key)
this.events = _.extend({}, this.genericEvents, this.events);
this.delegateEvents()
}
});
答案 1 :(得分:27)
另一种选择是让BaseView覆盖Extend的实现。如:
var BaseView = Backbone.View.extend({
//base view functionality if needed
});
BaseView.extend = function(child){
var view = Backbone.View.extend.apply(this, arguments);
view.prototype.events = _.extend({}, this.prototype.events, child.events);
return view;
};
这会自动扩展您从BaseView继承的所有事件。
答案 2 :(得分:10)
我喜欢Shaver先生的解决方案,但是对于那些不那么具有侵入性的东西:
var ChildView = ParentView.extend({
events : _.extend({
"change input": "handleInputChange"
}, ParentView.prototype.events)
});
编辑:是的,你必须在每个子类中执行此操作,但是当只需要几个孩子时,或者当你不控制父“class”时它会很有用。
答案 3 :(得分:3)
这是一个适合我的解决方案。您可以在父类和子类中使用events对象,而无需在每个子类中扩展它。只需在父类中扩展一次:
APP.Views.GenericWizard = Backbone.View.extend({
events: {
'click .btn-prev' : function(){}
},
initialize: function() {
_(this.events).extend(APP.Views.GenericWizard.prototype.events);
}
});
APP.Views.RegisterWizard = APP.Views.GenericWizard.extend({
events: {
'blur #username' : function(){}
},
});
var registerWizard = new APP.Views.RegisterWizard();
console.log(registerWizard.events);
// Object {blur #username: function, click .btn-prev: function}
答案 4 :(得分:1)
您可能会觉得这很有用:http://kalimotxocoding.blogspot.com/2011/03/playing-with-backbonejs-views.html
我提到的关于_.extend(...)
以及你现在拥有的内容的几分之二......