Hmm... interesting use of run
+ $rootScope
, but I would avoid it primarily because of $rootScope
. It's essentially the "global space" of an Angular app. The only legit use I see for it is attaching event listeners ($rootScope.$on
), and for broadcasting events ($rootScope.$emit
).
As an alternative, you could wrap your event relay in a factory.
As a factory, the dependency is explicit. The dependent knows it's there and Angular will throw if the dependency is missing on initialization, unlike
$rootScope
where it only throws when you use it.Factories are singletons. You don't have to worry about checking and using the existing or create a new one.
You're not polluting the
$rootScope
nor depending on something that might not be there or have been overridden by something in a lower, enclosing scope. This is a headache to debug, especially without tools like Batarang or ngInspector.
Additionally, you might also want to put your event names in a constant. That way, you have a global lookup of event names, and you won't be hardcoding string literals all over the app.
Here's an example of how it would look like as a factory (using implicit dependency injection syntax for brevity).
angular.module('SignalrModule', []);
.constant('SIGNALR_EVENTS', {
FOO_EVENT: 'fooevent',
BAR_EVENT: 'barevent',
})
.factory('SignalrFactory', function(){
return {
publish: function(){...},
subscribe: function(){...},
unsubscribe: function(){...},
};
});
angular.module('app', ['SignalrModule'])
.controller('MyController', function(SignalrFactory, SIGNALR_EVENTS){
SignalrFactory.subscribe(SIGNALR_EVENTS.FOO_EVENT, function(){
// on foo event
});
});
Now I did mention that angular has a built-in pub-sub system. We can just hook on to it so your controllers will simply use regular events over $rootScope
(we're not adding stuff to $rootScope
, just making it a relay for events). Not sure of the following works, but the concept is there.
angular.module('SignalrModule', []);
.constant('SIGNALR_EVENTS', {
FOO_EVENT: 'fooevent',
BAR_EVENT: 'barevent',
})
.run(function($rootScope, SIGNALR_EVENTS){
// Iterate through our registry of events
Object.keys(SIGNALR_EVENTS).forEach(function(eventName){
// Relay angular events to signalr over $rootScope
$rootScope.$on(SIGNALR_EVENTS[eventName], function(){
signalR.eventAggregator.publish(SIGNALR_EVENTS[eventName]);
});
// Relay signalr events to angular over $rootScope
signalR.eventAggregator.subscribe(SIGNALR_EVENTS[eventName], function(e) {
$rootScope.$emit(SIGNALR_EVENTS[eventName], e);
});
});
});
angular.module('app', ['SignalrModule'])
.controller('MyController', function($rootScope, SIGNALR_EVENTS){
// Using regular angular-ish emit and on
$rootScope.$emit(SIGNALR_EVENTS.FOO_EVENT, { foo: 'data' });
$rootScope.$on(SIGNALR_EVENTS.BAR_EVENT, function(){
// bar event emitted somewhere
});
});