In AngularJS, data sharing between controllers is essential when developing large-scale applications. There are multiple ways to achieve this, each with its own use case and benefits.
1. Using a Shared Service (Best Practice)
A service is the best and most efficient way to share data between controllers because: ✔ It follows AngularJS’s dependency injection model.
✔ The service persists data and maintains state across controllers.
✔ It is a singleton, meaning it maintains a single instance of data.
Example: Sharing Data with a Service
Step 1: Create a Service
var app = angular.module('myApp', []);
app.service('SharedService', function() {
var sharedData = "Initial Data";
this.getData = function() {
return sharedData;
};
this.setData = function(value) {
sharedData = value;
};
});
Step 2: Inject the Service into Controllers
app.controller('FirstController', function($scope, SharedService) {
$scope.data = SharedService.getData();
$scope.updateData = function() {
SharedService.setData($scope.data);
};
});
app.controller('SecondController', function($scope, SharedService) {
$scope.data = SharedService.getData();
$scope.refreshData = function() {
$scope.data = SharedService.getData();
};
});
Step 3: Create an HTML Template
<div ng-controller="FirstController">
<p>First Controller: <input type="text" ng-model="data"></p>
<button ng-click="updateData()">Update</button>
</div>
<div ng-controller="SecondController">
<p>Second Controller: {{ data }}</p>
<button ng-click="refreshData()">Refresh</button>
</div>
Explanation:
SharedService
stores and manages data.- The first controller updates the data.
- The second controller retrieves the updated data when the refresh button is clicked.
2. Using $rootScope
(Global Data Sharing)
✔ $rootScope
is a global scope object that can be accessed in all controllers.
✔ It should be used sparingly because modifying global scope can lead to performance issues.
Example: Sharing Data via $rootScope
app.controller('FirstController', function($scope, $rootScope) {
$rootScope.sharedMessage = "Hello from FirstController!";
});
app.controller('SecondController', function($scope, $rootScope) {
$scope.message = $rootScope.sharedMessage;
});
htmlCopyEdit<div ng-controller="FirstController">
<p>First Controller: {{ sharedMessage }}</p>
</div>
<div ng-controller="SecondController">
<p>Second Controller: {{ message }}</p>
</div>
Downsides of $rootScope
:
- Global data changes can affect all parts of the app, making debugging harder.
- Use services instead if data is only needed by specific controllers.
3. Using Events ($broadcast
, $emit
, $on
)
✔ AngularJS allows controllers to communicate through events.
✔ This is useful for parent-child controller communication.
Example: Broadcasting an Event
Step 1: Controller Sending an Event
app.controller('SenderController', function($scope, $rootScope) {
$scope.sendMessage = function() {
$rootScope.$broadcast('messageEvent', { text: "Hello from SenderController!" });
};
});
Step 2: Controller Receiving the Event
app.controller('ReceiverController', function($scope) {
$scope.$on('messageEvent', function(event, args) {
$scope.receivedMessage = args.text;
});
});
Step 3: HTML Template
<div ng-controller="SenderController">
<button ng-click="sendMessage()">Send Message</button>
</div>
<div ng-controller="ReceiverController">
<p>Received Message: {{ receivedMessage }}</p>
</div>
How it Works:
$broadcast
sends an event to all child scopes.$on
listens for the event and updates the message.$emit
can be used for parent-child communication instead of$broadcast
.
4. Using a Factory Instead of a Service
✔ A factory is similar to a service but uses a return object instead of this
.
✔ It is better for complex data structures.
Example: Using a Factory
app.factory('SharedFactory', function() {
var factory = {};
factory.data = "Shared Data";
factory.getData = function() {
return factory.data;
};
factory.setData = function(value) {
factory.data = value;
};
return factory;
});
app.controller('FirstController', function($scope, SharedFactory) {
$scope.data = SharedFactory.getData();
$scope.updateData = function() {
SharedFactory.setData($scope.data);
};
});
app.controller('SecondController', function($scope, SharedFactory) {
$scope.data = SharedFactory.getData();
});
Difference Between a Factory and a Service:
- Service: Uses
this
keyword. - Factory: Returns an object with functions.
- Both are singletons and store data persistently across controllers.
5. Using ng-model
and ng-bind
(Parent-Child Controllers)
✔ This method is useful when controllers are nested and use the same scope.
Example: Parent and Child Controller Sharing Data
app.controller('ParentController', function($scope) {
$scope.sharedText = "Shared Text";
});
<div ng-controller="ParentController">
<p>Parent: <input type="text" ng-model="sharedText"></p>
<div ng-controller="ChildController">
<p>Child: {{ sharedText }}</p>
</div>
</div>
Explanation:
- The child controller can access the
sharedText
variable from the parent scope.
Choosing the Right Method
Method | Use Case |
---|---|
Service / Factory | Best for managing persistent data between multiple controllers. |
$rootScope | Use only for truly global data. |
Events ($broadcast , $emit , $on ) | Best for parent-child or sibling communication. |
ng-model Binding | Works best in nested controllers. |