Last active
August 29, 2015 13:57
-
-
Save pascalpp/9589036 to your computer and use it in GitHub Desktop.
Backbone.When
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.