Directive scopes – @, =, and & bindings explained

Loading

In AngularJS, directives allow you to create reusable components. One key aspect of directives is how they interact with the scope. AngularJS provides three types of scope bindings to pass data between the parent scope and the directive’s isolated scope: @, =, and &. These bindings are defined in the directive’s scope property and control how data is passed to and from the directive.

Let’s break down these three types of bindings:

1. @ – One-way String Binding

The @ symbol is used for one-way string binding. When you use @, the value passed to the directive is treated as a string. The string is evaluated in the context of the parent scope and passed to the directive’s isolated scope.

How it works:

  • Parent to Directive: The value is passed from the parent scope to the directive, but it is treated as a string (e.g., 'someValue').
  • One-way binding: The data is passed only one way – from the parent to the directive. Changes in the directive will not be reflected back to the parent.

Example:

angular.module('app', [])
.directive('userCard', function() {
return {
restrict: 'E',
scope: {
userName: '@' // One-way string binding
},
template: '<h2>{{ userName }}</h2>'
};
});

Usage in HTML:

<user-card user-name="John Doe"></user-card>

Explanation:

  • user-name="John Doe": The user-name attribute is passed as a string value ('John Doe') to the directive.
  • The string "John Doe" is then passed into the directive’s isolated scope as userName.
  • One-way binding: Changes to userName in the directive will not be reflected in the parent scope.

When to Use:

  • Use the @ binding when you want to pass a simple string value (e.g., text or numbers) from the parent scope to the directive.

2. = – Two-way Binding

The = symbol is used for two-way data binding. With this binding, changes to the data in the directive will be reflected in the parent scope, and vice versa. This allows the parent scope to access the directive’s data and allows the directive to update the data in the parent scope.

How it works:

  • Parent to Directive: The value is passed from the parent scope to the directive, and both the parent and directive are connected to the same data. Any changes in either will be reflected in the other.
  • Two-way binding: Both directions of data flow are maintained. This is similar to how Angular’s ng-model works for form inputs.

Example:

angular.module('app', [])
.directive('userProfile', function() {
return {
restrict: 'E',
scope: {
userDetails: '=' // Two-way binding
},
template: `
<div>
<p>{{ userDetails.name }}</p>
<button ng-click="userDetails.age = 31">Update Age</button>
</div>`
};
});

Usage in HTML:

<div ng-app="app">
<user-profile user-details="user"></user-profile>
</div>

Explanation:

  • user-details="user": The user object in the parent scope is bound to the userDetails property in the directive.
  • Any changes made to userDetails in the directive, such as updating the age, will be reflected in the parent scope (user.age).
  • Two-way binding: Changes in the userDetails object inside the directive (like the button click that updates age) will update the parent scope, and vice versa.

When to Use:

  • Use = when you need to pass an object, array, or complex data to the directive, and you want any changes in the directive to affect the parent scope.

3. & – Function Binding

The & symbol is used for passing functions from the parent scope to the directive. This allows the directive to call a function defined in the parent scope. The function can be invoked from within the directive and can pass data back to the parent scope.

How it works:

  • Parent to Directive: The function from the parent scope is passed to the directive.
  • Directive to Parent: The directive can invoke this function, possibly passing arguments, and execute code in the parent scope.

Example:

angular.module('app', [])
.directive('greeting', function() {
return {
restrict: 'E',
scope: {
onGreet: '&' // Function binding
},
template: '<button ng-click="onGreet()">Greet</button>'
};
});

Usage in HTML:

<div ng-app="app" ng-controller="MainCtrl">
<greeting on-greet="greetUser()"></greeting>
</div>

Controller:

angular.module('app').controller('MainCtrl', function($scope) {
$scope.greetUser = function() {
alert('Hello, User!');
};
});

Explanation:

  • on-greet="greetUser()": The greetUser function from the parent scope is passed into the directive via the onGreet property.
  • Inside the directive, the onGreet function is called when the button is clicked. This triggers the greetUser function in the parent scope, which shows an alert.

When to Use:

  • Use & when you want the directive to invoke a function in the parent scope, allowing for custom actions or event handling.

Comparison of @, =, and & Bindings

Binding TypeDescriptionOne-Way or Two-WayUse CaseExample
@String bindingOne-way binding (parent to directive)Use when passing a string (e.g., text, numbers) to the directive.<my-directive text="Hello"></my-directive>
=Two-way bindingTwo-way binding (parent ↔ directive)Use when passing objects/arrays, and you want changes reflected in both the directive and parent.<my-directive user="userObject"></my-directive>
&Function bindingOne-way binding (directive to parent function)Use when you need to pass a function from the parent scope to the directive to invoke custom behavior.<my-directive on-action="doSomething()"></my-directive>

Leave a Reply

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