I've been told that using angular events can be expensive (I've been unable to verify this)
Any calls to $broadcast
and $on
should be 'wrapped' with a factory or service to inject into their corresponding components to preserve performance?
Again I'd rather use $on
and listen directly to the events being fired rather than creating a factory that in essence is just going to register functions to call when it receives the event - lets call this a dispatcher.
Please note that it's not just one component (directives) listening to 'some-event' there will be a variety of components listening to this event.
Example dispatcher:
angular.module('app').factory('dispatcher', ['$rootScope', function ($rootScope) {
var registeredFns = [ ];
$rootScope.$on('some-event', function (evt, msg) {
_.each(registeredFns, function (fn) {
fn.apply(null, msg);
});
});
return {
onSomeEvent: function (fn) {
registeredFns.push(fn);
}
};
});
And inject it where I need it - maybe a directive, maybe a controller where ever it doesn't matter.
Broadcast: We can pass the value from parent to child (i.e parent -> child controller.) Emit: we can pass the value from child to parent (i.e.child ->parent controller.) On: catch the event dispatched by $broadcast or $emit .
$broadcast() as well as $emit() allow you to raise an event in your AngularJS application. The difference between $broadcast() and $emit() is that the former sends the event from the current controller to all of its child controllers. That means $broadcast() sends an even downwards from parent to child controllers.
Scope(s) can be used to propagate, dispatch event to the scope children or parent. $emit - propagates the event to parent. $broadcast - propagates the event to children.
$emit() allows you to raise an event in your AngularJS application. It sends an event upwards from the current controller to all of its parent controllers. From the syntax point-of-view, a typical call to $emit() will look like this: $scope. $emit("MyEvent",date);
They're not expensive at all... but they're potentially expensive if they're misused (like anything else in life - this sounds like the start of a good joke!)
It's important to understand what's actually happening in here, and the code is actually pretty straightforward. If you call $emit(), it just does a for()
loop across the array of registered listeners and calls each one. It does this on the scope you first call it on, and then walks "up" each parent until it hits $rootScope.
There's a little bit of extra code to handle things like stopPropagation, but otherwise that's it.
$broadcast does something similar, but in the opposite direction: it does this for() loop but then goes through every child scope. That's a super important difference, because if you do a $rootScope.$broadcast()
and you have a lot of ngRepeats and directives floating around, you could be doing a huge amount more work than you expect - even if none of those scopes listen for this event, Angular still has to go through them all to figure that out.
Your fastest use-case if you want to do the fastest possible test in jsPerf or similar would be to use $rootScope.$emit()
and $rootScope.$on()
. That will give you a single-scope test for basic message passing and you can go from there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With