How to use one-way binding in AngularJS components

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:

  1. Parent assigns userName = "John Doe".
  2. Child receives name = "John Doe".
  3. 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"), $onChanges does NOT trigger.
  • If the reference changes (this.user = {}), $onChanges triggers.

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 TypeSyntaxParent 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.

Leave a Reply

Your email address will not be published. Required fields are marked *