In AngularJS, event-driven communication allows different components of an application to communicate with each other efficiently. AngularJS provides the $broadcast and $emit methods on $scope
to send events, along with $on
to listen for them.
This guide will explore:
- The differences between
$broadcast
and$emit
- How to use them effectively with examples
- Best practices and when to use them
Step 1: Understanding $emit
, $broadcast
, and $on
1. $emit(eventName, data)
- Sends an event upwards from the current
$scope
to its parent scopes, up to the$rootScope
. - Only parent scopes and
$rootScope
can listen to this event. - Typically used when a child scope needs to notify a parent or global scope.
2. $broadcast(eventName, data)
- Sends an event downwards from the current
$scope
to all its child scopes. - Only child scopes can listen to this event.
- Typically used when a parent scope wants to notify its children.
3. $on(eventName, callback)
- Used to listen for events (
$emit
or$broadcast
) in any scope.
Step 2: Using $emit
to Communicate Upwards
Imagine a scenario where a child controller needs to notify the parent controller when an action occurs.
Example – Using $emit
to Notify the Parent Scope
HTML
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<title>AngularJS $emit Example</title>
</head>
<body ng-controller="ParentCtrl">
<h2>Parent Received: {{ parentMessage }}</h2>
<div ng-controller="ChildCtrl">
<button ng-click="sendMessage()">Send Message to Parent</button>
</div>
<script src="app.js"></script>
</body>
</html>
JavaScript (app.js
)
var app = angular.module('app', []);
app.controller('ParentCtrl', function($scope) {
$scope.parentMessage = "No message received";
// Listen for the event emitted from the child scope
$scope.$on('childEvent', function(event, data) {
$scope.parentMessage = data; // Update the parent scope
});
});
app.controller('ChildCtrl', function($scope) {
$scope.sendMessage = function() {
$scope.$emit('childEvent', 'Message from Child!'); // Emit event upwards
};
});
How It Works
- The Child Controller emits the event
childEvent
using$scope.$emit()
. - The Parent Controller listens for the event using
$scope.$on()
. - When the button is clicked, the event triggers and updates the parent’s message.
Use $emit
when a child needs to communicate with a parent or $rootScope
.
Step 3: Using $broadcast
to Communicate Downwards
Now, let’s see how a parent controller can notify its child controllers using $broadcast
.
Example – Using $broadcast
to Notify Child Scopes
HTML
<body ng-controller="ParentCtrl">
<button ng-click="sendBroadcast()">Send Broadcast to Children</button>
<div ng-controller="ChildCtrl">
<h2>Child Message: {{ childMessage }}</h2>
</div>
</body>
JavaScript (app.js
)
app.controller('ParentCtrl', function($scope) {
$scope.sendBroadcast = function() {
$scope.$broadcast('parentEvent', 'Message from Parent!');
};
});
app.controller('ChildCtrl', function($scope) {
$scope.childMessage = "No message received";
$scope.$on('parentEvent', function(event, data) {
$scope.childMessage = data; // Update child scope with the message
});
});
How It Works
- The Parent Controller sends an event
parentEvent
using$scope.$broadcast()
. - The Child Controller listens for
parentEvent
using$scope.$on()
. - When the button is clicked, the event triggers and updates the child’s message.
Use $broadcast
when a parent needs to notify its children.
Step 4: Using $rootScope.$emit
and $rootScope.$broadcast
for Global Events
If you need an event to be available throughout the application, use $rootScope
.
Example – Global Event Communication Using $rootScope.$emit
HTML
<body ng-controller="GlobalCtrl">
<button ng-click="notifyAll()">Notify All Controllers</button>
<div ng-controller="ChildCtrl">
<h2>Child Received: {{ childMessage }}</h2>
</div>
</body>
JavaScript (app.js
)
app.run(function($rootScope) {
$rootScope.$on('globalEvent', function(event, data) {
console.log("Global Event Received: ", data);
});
});
app.controller('GlobalCtrl', function($scope, $rootScope) {
$scope.notifyAll = function() {
$rootScope.$emit('globalEvent', 'This is a global event!');
};
});
app.controller('ChildCtrl', function($scope, $rootScope) {
$scope.childMessage = "No global event yet";
$rootScope.$on('globalEvent', function(event, data) {
$scope.childMessage = data;
});
});
How It Works
$rootScope.$emit()
triggers a global event.- Any controller listening on
$rootScope
can receive this event.
Use $rootScope.$emit
for application-wide event communication.
Step 5: Best Practices for Event Handling
Best Practice | Explanation |
---|---|
Minimize Global Events | $rootScope.$emit and $rootScope.$broadcast should be used sparingly to avoid complexity. |
Unregister Event Listeners | Use $scope.$on('$destroy', function() { ... }) to clean up event listeners when a scope is destroyed. |
Use Services for Shared Data | If two controllers need to share data, using a service is often a better option. |
Avoid Excessive $broadcast and $emit | Too many events can make debugging difficult. Consider direct function calls or services instead. |
Conclusion
Method | Communication Direction | Use Case |
---|---|---|
$emit | Upwards to parent scope | When a child needs to notify a parent |
$broadcast | Downwards to child scopes | When a parent needs to notify its children |
$rootScope.$emit | Global event for all controllers | When an event should be available app-wide |
$on | Listening for events | Used to capture emitted or broadcasted events |
Use $emit
for child-to-parent communication.
Use $broadcast
for parent-to-child communication.
Use $rootScope.$emit
sparingly for global events.