Skip to content

Instantly share code, notes, and snippets.

@pascalpp
Last active August 29, 2015 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pascalpp/9589036 to your computer and use it in GitHub Desktop.
Save pascalpp/9589036 to your computer and use it in GitHub Desktop.
Backbone.When
define(function(require) {
'use strict';
/* MODULE DEPENDENCIES */
var Backbone = require('backbone'),
_ = require('underscore');
/*
Backbone.When
2014-02-20 by pascal
Backbone.When is a mixin which adds event history to objects with Backbone.Events
usage:
var When = require('lib/backbone.when');
When.applyTo(SomeObject);
SomeObject can be any Backbone class which has Backbone.Events mixed in.
SomeObject will now have a .when method, so that other modules can do:
SomeObject.when('ready', handler, context);
// or any other event name, not just 'ready'
and if 'ready' has already been triggered on SomeObject, the handler will
be called immediately. If not, a once listener will be set on the object
so that when the event eventually gets triggered, the handler will fire.
*/
var When = {};
// use this method to apply Backbone.When to your object
When.applyTo = function(obj) {
if (obj && obj.prototype && obj.prototype.on === Backbone.Events.on) {
// item already has Backbone.Events
// so it's safe to mixin Backbone.When
_.extend(obj.prototype, When.Events);
} else {
console.error('This object does not have Backbone.Events');
}
};
When.Events = {
// override Backbone.Events.trigger to insert an entry into _past_events
trigger: function(event_name) {
this._past_events || (this._past_events = {});
var args = Array.prototype.slice.call(arguments, 1);
this._past_events[event_name] = args;
return Backbone.Events.trigger.apply(this, arguments);
},
forget: function(event_name) {
this._past_events || (this._past_events = {});
delete this._past_events[event_name];
},
// this method checks to see if an event has already been triggered
// if so, the handler is called immediately
// if not, a regular this.once listener is applied
when: function(event_name, handler, context) {
this._past_events || (this._past_events = {});
var past_args = this._past_events[event_name];
if (past_args) {
handler.apply(context, past_args);
return this;
} else {
this.once.apply(this, arguments);
return this;
}
},
// similar to .when, this method calls the handler immediately if the
// event has already been triggered, but it sets a .on listener so that
// any subsequent triggers will also call the handler
whenever: function(event_name, handler, context) {
this._past_events || (this._past_events = {});
var past_args = this._past_events[event_name];
if (past_args) {
handler.apply(context, past_args);
}
this.on.apply(this, arguments);
return this;
}
};
return When;
});
@pascalpp
Copy link
Author

This is an AMD module I wrote. I looked around for the ability to track event history with Backbone.Events but didn’t find a solution, so I wrote this one. I’m somewhat new to Backbone, so feedback on this idea from experienced Backbone developers would be most welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment