In AngularJS 1.5+, one-way binding (<) is a mechanism for passing data from a parent component to a child component, but the child cannot modify the parent’s value directly.
1. What is One-Way Binding (<)?
One-way binding in AngularJS components:
- Allows a parent component to pass data to a child component.
- Prevents the child from modifying the parent’s data directly.
- Updates the child whenever the parent’s value changes.
Syntax in Component Bindings:
bindings: {
propertyName: '<'
}
2. Basic Example of One-Way Binding
Step 1: Define the Parent Component
app.component('parentComponent', {
template: `
<h2>Parent Component</h2>
<input type="text" ng-model="$ctrl.userName">
<child-component name="$ctrl.userName"></child-component>
`,
controller: function() {
this.userName = "John Doe"; // Initial value
}
});
- Data (
userName) is bound to<child-component>. - If the user updates the input, the child receives the new value.
Step 2: Define the Child Component
app.component('childComponent', {
bindings: {
name: '<' // One-way binding from parent
},
template: `<p>Child Component: {{$ctrl.name}}</p>`,
controller: function() {
this.$onChanges = function(changes) {
if (changes.name) {
console.log("Parent Updated Name:", changes.name.currentValue);
}
};
}
});
How it Works:
- Parent assigns
userName = "John Doe". - Child receives
name = "John Doe". - If the parent updates
userName, the child automatically updates.
3. One-Way Binding with Objects
If the parent passes an object, the child sees the latest object reference but cannot modify the original data.
Parent Component
app.component('parentComponent', {
template: `
<h2>Parent Component</h2>
<button ng-click="$ctrl.updateUser()">Update User</button>
<child-component user="$ctrl.user"></child-component>
`,
controller: function() {
this.user = { name: "John Doe" };
this.updateUser = function() {
this.user = { name: "Jane Smith" }; // Changing reference
};
}
});
Child Component
app.component('childComponent', {
bindings: {
user: '<'
},
template: `<p>User Name: {{$ctrl.user.name}}</p>`,
controller: function() {
this.$onChanges = function(changes) {
if (changes.user) {
console.log("User updated:", changes.user.currentValue);
}
};
}
});
Key Takeaways:
- The child receives the latest reference of the object.
- If only properties change (
this.user.name = "New Name"),$onChangesdoes NOT trigger. - If the reference changes (
this.user = {}),$onChangestriggers.
4. Preventing Child from Modifying Parent Data
Even though one-way binding prevents direct modification, the child can still modify object properties if the reference remains unchanged.
Prevent Modification Using $onChanges
Modify the child controller to always create a copy:
app.component('childComponent', {
bindings: {
user: '<'
},
template: `<input type="text" ng-model="$ctrl.localUser.name">`,
controller: function() {
this.$onChanges = function(changes) {
if (changes.user) {
this.localUser = angular.copy(changes.user.currentValue); // Prevent modifying original object
}
};
}
});
Now, modifying localUser.name does not change the parent’s user.name.
5. One-Way Binding vs Two-Way Binding
| Binding Type | Syntax | Parent Affects Child? | Child Affects Parent? |
|---|---|---|---|
One-Way (<) | bindings: { name: '<' } | Yes | No |
Two-Way (=) | bindings: { name: '=' } | Yes | Yes |
Use one-way binding (<) when:
- The parent controls the data and updates should flow downward.
- You want to avoid accidental modifications from the child.
6. When to Use One-Way Binding
When passing static or read-only data to a child.
When working with nested components where only the parent should control data.
When preventing unwanted modifications in child components.
Avoid one-way binding if the child needs to update the parent’s value. Use two-way binding (=) or events (&) instead.
