$rootScope.$broadcast vs. $scope.$emit
Now that the performance difference between $broadcast
and $emit
has been eliminated, is there any reason to prefer $scope.$emit
to $rootScope.$broadcast
?
They are different, yes.
$emit
is restricted to the scope hierarchy (upwards) - this may be good, if it fits your design, but it seems to me a rather arbitrary restriction.
$rootScope.$broadcast
works across all that choose to listen to the event, which is a more sensible restriction in my mind.
Am I missing something?
EDIT:
To clarify in response to an answer, the direction of the dispatch is not the issue I'm after. $scope.$emit
dispatches the event upwards, and $scope.$broadcast
- downwards. But why not always use $rootScope.$broadcast
to reach all the intended listeners?
Solution 1:
tl;dr (this tl;dr is from @sp00m's answer below)
$emit
dispatches an event upwards ...$broadcast
dispatches an event downwards
Detailed explanation
$rootScope.$emit
only lets other $rootScope
listeners catch it. This is good when you don't want every $scope
to get it. Mostly a high level communication. Think of it as adults talking to each other in a room so the kids can't hear them.
$rootScope.$broadcast
is a method that lets pretty much everything hear it. This would be the equivalent of parents yelling that dinner is ready so everyone in the house hears it.
$scope.$emit
is when you want that $scope
and all its parents and $rootScope
to hear the event. This is a child whining to their parents at home (but not at a grocery store where other kids can hear).
$scope.$broadcast
is for the $scope
itself and its children. This is a child whispering to its stuffed animals so their parents can't hear.
Solution 2:
They are not doing the same job: $emit
dispatches an event upwards through the scope hierarchy, while $broadcast
dispatches an event downwards to all child scopes.
Solution 3:
I made the following graphic out of the following link: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
As you can see, $rootScope.$broadcast
hits a lot more listeners than $scope.$emit
.
Also, $scope.$emit
's bubbling effect can be cancelled, whereas $rootScope.$broadcast
cannot.
Solution 4:
$scope.$emit: This method dispatches the event in the upwards direction (from child to parent)
$scope.$broadcast: Method dispatches the event in the downwards direction (from parent to child) to all the child controllers.
$scope.$on: Method registers to listen to some event. All the controllers which are listening to that event get notification of the broadcast or emit based on the where those fit in the child-parent hierarchy.
The $emit event can be cancelled by any one of the $scope who is listening to the event.
The $on provides the "stopPropagation" method. By calling this method the event can be stopped from propagating further.
Plunker :https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/
In case of sibling scopes (the scopes which are not in the direct parent-child hierarchy) then $emit and $broadcast will not communicate to the sibling scopes.
For more details please refer to http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html