In AngularJS 1.5+, components follow a unidirectional data flow, meaning that child components cannot directly modify parent component data. Instead, AngularJS provides mechanisms like one-way binding (<) and callback functions (&) to allow child components to update the parent component.
1. Methods to Update a Parent from a Child
There are three main ways to update a parent component from a child:
- Using
&binding (Best Practice) → Parent passes a callback function to child. - Using a shared service → Useful when multiple components share data.
- Using
$scope.$emit()and$scope.$on()→ Used in$scope-based applications but less recommended.
2. Updating Parent Using & Binding (Recommended)
This is the best and most AngularJS-friendly approach.
- The parent component passes a function to the child component.
- The child component calls this function when an event occurs (like a button click).
- The parent component updates its data accordingly.
Step 1: Parent Component (parentComponent)
- Defines the
updateMessage()function. - Passes it to the child using
&binding.
app.component('parentComponent', {
template: `
<div>
<h3>Parent Component</h3>
<p>Message: {{$ctrl.message}}</p>
<child-component on-update="$ctrl.updateMessage(newMessage)"></child-component>
</div>
`,
controller: function() {
this.message = "Hello from Parent";
this.updateMessage = function(newMessage) {
this.message = newMessage; // Update parent data
};
}
});
The parent provides the updateMessage() function to be called by the child.
Step 2: Child Component (childComponent)
- Defines a button that calls
onUpdate({ newMessage: "Updated from Child!" }).
app.component('childComponent', {
bindings: {
onUpdate: '&' // Accepts function reference from parent
},
template: `
<div>
<h3>Child Component</h3>
<button ng-click="$ctrl.sendUpdate()">Update Parent</button>
</div>
`,
controller: function() {
this.sendUpdate = function() {
this.onUpdate({ newMessage: "Updated from Child!" }); // Call parent function
};
}
});
The child calls onUpdate(), triggering the parent’s updateMessage().
The parent component updates its message, reflecting the change.
3. Using a Shared Service (When Siblings Need to Update Parent)
If multiple components (e.g., siblings) need to update the parent, a service can manage shared data.
Step 1: Create a Shared Service
app.factory('MessageService', function() {
let message = "Hello from Parent";
let callback = null;
return {
setMessage: function(newMessage) {
message = newMessage;
if (callback) callback(newMessage); // Notify parent
},
getMessage: function() {
return message;
},
subscribe: function(cb) {
callback = cb;
}
};
});
The service stores the message and notifies the parent when updated.
Step 2: Parent Component (parentComponent)
app.component('parentComponent', {
template: `
<div>
<h3>Parent Component</h3>
<p>Message: {{$ctrl.message}}</p>
<child-component></child-component>
</div>
`,
controller: function(MessageService) {
let ctrl = this;
ctrl.message = MessageService.getMessage();
MessageService.subscribe(function(newMessage) {
ctrl.message = newMessage;
});
}
});
The parent subscribes to the service to update its message when notified.
Step 3: Child Component (childComponent)
app.component('childComponent', {
template: `
<div>
<h3>Child Component</h3>
<button ng-click="$ctrl.updateMessage()">Update Parent</button>
</div>
`,
controller: function(MessageService) {
this.updateMessage = function() {
MessageService.setMessage("Updated from Child!"); // Updates service message
};
}
});
The child updates the message via MessageService, and the parent automatically updates.
Best for complex applications with multiple components sharing data.
4. Using $scope.$emit() and $scope.$on() (Less Recommended)
If working with older $scope-based applications, you can use $emit() in the child and $on() in the parent.
Step 1: Parent Listens for Event
app.component('parentComponent', {
template: `
<div>
<h3>Parent Component</h3>
<p>Message: {{$ctrl.message}}</p>
<child-component></child-component>
</div>
`,
controller: function($scope) {
let ctrl = this;
ctrl.message = "Hello from Parent";
$scope.$on('messageUpdated', function(event, newMessage) {
ctrl.message = newMessage;
});
}
});
Parent listens for messageUpdated event and updates message.
Step 2: Child Emits Event
app.component('childComponent', {
template: `
<div>
<h3>Child Component</h3>
<button ng-click="$ctrl.sendUpdate()">Update Parent</button>
</div>
`,
controller: function($scope) {
this.sendUpdate = function() {
$scope.$emit('messageUpdated', "Updated from Child!");
};
}
});
Child emits an event to notify the parent.
This method is less recommended because:
$emit()and$on()rely on$scope, which is not used in newer AngularJS components.- Harder to debug and scale.
- Use services or
&binding instead.
5. Comparison of Methods
| Method | Use Case | Pros | Cons |
|---|---|---|---|
& Binding (Callback) | Direct child-to-parent updates | Simple, built-in, recommended | Only works for direct parent-child |
| Shared Service | Multiple components updating parent | Works across unrelated components | Requires service setup |
$emit & $on | $scope-based apps | Works without additional setup | Not recommended for components |
6. When to Use Each Approach
Use & binding when the child directly updates the parent.
Use a service when multiple components share the same data.
Avoid $emit and $on in modern AngularJS applications.
