I have a generic subclass of Backbone.View
which has a close
event listener.
var GenericView = Backbone.View.extend({ events : { "click .close" : "close" }, close : function () { console.log("closing view"); } });
I want to subclass this generic class and add some new events. However the below will overwrite the super classes (above) event object. E.g.
var ImplementedView = new GenericView({ // setting this will stop 'close' in Super Class from triggering events : { "click .submit" : "submit" } });
How should I create a sub class, in this case ImplementedView
and retain the events?
I have found one way to achieve this, by extending the event object when the child class is constructed. However I need to re-trigger this.delegateEvents()
, which I am guessing is not good. Can any one comment on this?
var ImplementedView = new GenericView({ initialize : function (options) { _.extend(this.events, { "click .submit" : "submit" }); // re-attach events this.delegateEvents(); } });
@Nupul is exactly right: you're not subclassing your GenericView
.
In fact, subclassing isn't really the right word here, since JavaScript doesn't do classical inheritance.
So let's first try and understand what's happening here:
var GenericView = Backbone.View.extend( propertiesObj, classPropertiesObj )
Backbone.View
is a constructor function, that when called with the new
keyword, creates a new object for you.
Since this is JS, all function are really function objects, so Backbone.View.extend
is just a function hanging off Backbone.View
that does a few things:
GenericView
) to instantiate objects of your inheriting classSo the correct way to set up the protoype chain you want is:
var ImplementedView = GenericView.extend({ // implementation goes here });
and NOT:
var ImplementedView = new GenericView({//stuff});
because this just creates a new instance of a GenericView.
Now, you still have a problem, because when you do something like:
var impl_view = new ImplementedView; impl_view.events; // This isn't merged with the events you created // for the GenericView
At this point there are different ways to get the result you want, here's one that uses delegateEvents
kind of like how you did. Using it isn't bad, incidentally.
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() } });
Another option is to have a BaseView that overrides the implementation of Extend. Such as:
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; };
This will automatically extend all of your events for anything that inherits from the BaseView.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With