Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Make backbone.js inhertance work for you! (or make view inheritance work in general)
/**
* Give backbone an easier way to access super properties and methods.
*/
Backbone.View.prototype.parent = Backbone.Model.prototype.parent = Backbone.Collection.prototype.parent = function(attribute, options) {
/**
* Call this inside of the child initialize method. If it's a view, it will extend events also.
* this.parent('inherit', this.options); <- A views params get set to this.options
*/
if(attribute == "inherit") {
this.parent('initialize', options); // passes this.options to the parent initialize method
//extends child events with parent events
if(this.events) { $.extend(this.events, this.parent('events')); this.delegateEvents(); }
return;
}
/**
* Call other parent methods and attributes anywhere else.
* this.parent('parentMethodOrOverriddenMethod', params) <- called anywhere or inside overridden method
* this.parent'parentOrOverriddenAttribute') <- call anywhere
*/
return (_.isFunction(this.constructor.__super__[attribute])) ?
this.constructor.__super__[attribute].apply(this, _.rest(arguments)) :
this.constructor.__super__[attribute];
};
var ParentView = Backbone.View.extend({
'anAttribute': "YO!",
'events': {
'click .parentSomething': "handleParentSomethingClick"
},
'handleParentSomethingClick': function() {
console.log('parent something was clicked.');
},
'parentOnlyFunction': function(arg) {
console.log('a function only in the parent view with arg:', arg);
}
});
var ChildView = ParentView.extend({
'initialize': function() {
//inherits events and calls the parent initialize with options
this.parent('inherit', this.options);
//calls parentOnlyFunction and outputs "Hello Parent Only Function" at the end of the console log
this.parent('parentOnlyFunction', "Hello Parent Only Function!");
//logs "YO!"
console.log(this.parent('anAttribute'));
},
'events': {
'click .something': "handleSomethingClick"
},
'handleSomethingClick': function() {
console.log('something was clicked.');
}
});
@fcamblor

Hi !

I noticed a problem in your implementation regarding Backbone.Model.initialize() method wich takes not only options but attributes too.
I think in your current implementation, you should distinguish this particular case because, for now, calling :
this.parent("inherit", ...)

doesn't allow to initialize Model's attributes given to the constructors as we would do by calling :
initialize: function(attributes, options){
Backbone.Model.prototype.initialize.call(this, attributes, options);
}

By the way, I like your gist because it simplify my life :

  • code is simpler
  • If I change my parent class, I won't have to track every Backbone.XXX.prototype.mymethod.call()
@dlidstrom

Here's a version that works in the presence of _.bindAll:

Backbone.View.prototype.parent = function (attribute, options) {
  // keep a reference to this
  var self = this;
  /**
   * Call this inside of the child initialization method.
   * It will extend events.
   * this.parent('inherit', this.options); // a views params get set to this.options
   */
  if (attribute == 'inherit') {
    // passes this.options to the parent initialize method
    self.parent('initialize', options);

    // extends child events with parent events
    if (self.events) {
      var parentEvents = self.parent('events');
      $.extend(self.events, parentEvents);
      self.delegateEvents();
    }

    return undefined;
  }

  /**
   * Call other parent methods and attributes anywhere else.
   * this.parent('parentMethodOrOverriddenMethod', params); <- called anywhere or inside overridden method
   * this.parent('parentOrOverriddenAttribute') <- call anywhere
   */
  var value = self.constructor.__super__[attribute];
  if (_.isFunction(value))
    return value.apply(self, _.rest(arguments));
  return value;
};
@dlidstrom

Sorry, that is not necessary. Just don't do _.bindAll in the parent initialize method. It seems it is only necessary in the child initialize.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.