Skip to content

Instantly share code, notes, and snippets.

@henrahmagix
Last active August 29, 2015 14:17
Show Gist options
  • Save henrahmagix/4d4d04a09298a493f804 to your computer and use it in GitHub Desktop.
Save henrahmagix/4d4d04a09298a493f804 to your computer and use it in GitHub Desktop.
A method for using $rootScope as a global events bus. Currently leaky: need to delete events after deregistration.
app.service('AppEvents', [
'$rootScope', '$log',
function ($rootScope, $log) {
// Store for callback functions.
this._events = {};
// Deregister an event.
var deregister = function (offFunc) {
if (offFunc) {
offFunc();
return true;
}
return false;
};
// Store the deregistration function mapped to the handler and name.
this.on = function (name, handler) {
var offFunc = $rootScope.$on.apply($rootScope, arguments);
if (!this._events[name]) {
this._events[name] = {};
}
this._events[name][handler.toString()] = offFunc;
};
// Deregister a single event by its name and handler, all events for
// a given name, or all events ever registered.
this.off = function (name, handler) {
var success = true;
if (handler && name) {
// Remove just one event by the handler.
var handlerString = handler.toString();
if (!this._events[name] || !this._events[name][handlerString]) {
success = false;
} else {
var offFunc = this._events[name][handlerString];
success = deregister(offFunc);
}
} else if (name) {
// Remove all events under a name.
var hasLooped = false;
angular.forEach(this._events[name], function (offFunc) {
hasLooped = true;
var removed = deregister(offFunc);
if (!removed) {
success = false;
}
});
if (!hasLooped) {
success = false;
}
} else {
// Remove all events.
angular.forEach(this._events, function (savedEventObj, name) {
angular.forEach(savedEventObj, function (offFunc) {
var removed = deregister(offFunc);
if (!removed) {
success = false;
}
});
});
}
// Warn if event removal was unsuccessful.
if (!success) {
$log.warn('Cannot deregister ' + name);
}
};
// Trigger an event. This passes straight through to $rootScope.
this.trigger = function () {
$rootScope.$emit.apply($rootScope, arguments);
};
}
]);
// Somewhere in an Angular thing with AppEvents injected.
AppEvents.on('whatHasHappened', function ($event, thing) {
console.log(thing + ' has happened');
});
AppEvents.trigger('whatHasHappened', 'nothing');
// 'nothing has happened'
// Remove events.
AppEvents.off('whatHasHappened');
// Optionally pass the handler for greater specificity, or pass no
// parameters to remove all events.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment