Philip Kirkbride
Philip Kirkbride

Reputation: 22889

Backbone defaults view events

Is it possible to make a set of default events which exist in every view? For example if every view in my application includes a settings button

        events: {
            "click #settings" : "goSettings"
        },
        ...
        goSettings: function() {
            // settings show function
        });

How can I can package this event to be included in every view in my application?

Upvotes: 1

Views: 270

Answers (2)

kielni
kielni

Reputation: 4999

You can create a base view with the event(s) and functions, then make your other views inherit from it. I like the pattern described here, because it's simple to set up and easy to override as needed: http://www.scottlogic.com/blog/2012/12/14/view-inheritance-in-backbone.html

A base view looks like this:

var BaseSearchView = function(options) {
  this.inheritedEvents = [];
  Backbone.View.call(this, options);
}

_.extend(BaseView.prototype, Backbone.View.prototype, {
  baseEvents: {},

  initialize: function(options) {
    // generic initialization here
    this.addEvents({
      "click #settings" : "goSettings"
    });
    this.initializeInternal(options);
  },

  render: function() {
    // generic render here
    this.renderInternal();
    return this;
  },

  events: function() {
    var e = _.extend({}, this.baseEvents);
    _.each(this.inheritedEvents, function(events) {
      e = _.extend(e, events);
    });
    return e;
  },

  addEvents: function(eventObj) {
    this.inheritedEvents.push(eventObj);
  },

  goSettings: function() {
        // settings show function
  }
});

BaseView.extend = Backbone.View.extend;

And your child classes like this:

var MyView = BaseView.extend({

  initializeInternal: function(options) {
    // do something
    // add event just for this child
    this.addEvents({
      "click #differentSettings" : "goSettings"
    });

  },
  renderInternal: function() {
    // do something
  }
});

Upvotes: 2

mu is too short
mu is too short

Reputation: 434805

The problem is that View#extend simply overwrites existing properties so you can't put your 'click #settings' in a base class and subclass that. However, you can easily replace extend with something of your own that merges events. Something like this:

var B = Backbone.View.extend({
    events: {
        'click #settings': 'goSettings'
    }
}, {
    extend: function(properties, classProperties) {
        properties.events = _({}).extend(
            properties.events || { },
            this.prototype.events
        );
        return Backbone.View.extend.call(this, properties, classProperties);
    }
});

And then extend B instead of Backbone.View for your views.

Demo: http://jsfiddle.net/ambiguous/Kgh3V/

Upvotes: 4

Related Questions