How to bind multiple models in a custom directive?

Loading

When creating custom directives in AngularJS, you may need to bind multiple models to the directive’s scope. This allows your directive to interact with different data sources dynamically.


Step 1: Understanding Scope Binding in Directives

AngularJS provides three types of scope binding in directives:

  1. = (Two-way binding) – Syncs between parent scope and directive scope.
  2. @ (One-way string binding) – Passes strings as attributes.
  3. & (Function binding) – Allows calling parent scope functions.

For multiple model bindings, we typically use = for objects and @ for static values.


Step 2: Creating a Directive with Multiple Bindings

Let’s create a custom directive that binds multiple models like name, age, and profession.

Example – Two-Way Data Binding with =

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<title>Multi-Model Directive</title>
</head>
<body ng-controller="MainCtrl">

<user-info name="user.name" age="user.age" profession="user.profession"></user-info>

<script>
var app = angular.module('app', []);

// Main Controller
app.controller('MainCtrl', function($scope) {
$scope.user = {
name: "John Doe",
age: 30,
profession: "Software Engineer"
};
});

// Custom Directive
app.directive('userInfo', function() {
return {
restrict: 'E',
scope: {
name: '=',
age: '=',
profession: '='
},
template: `
<div>
<h3>User Info</h3>
<p><strong>Name:</strong> {{name}}</p>
<p><strong>Age:</strong> {{age}}</p>
<p><strong>Profession:</strong> {{profession}}</p>
</div>
`
};
});
</script>

</body>
</html>

How It Works

  • name="user.name" → Two-way binds user.name to name in directive.
  • age="user.age" → Two-way binds user.age to age.
  • profession="user.profession" → Two-way binds user.profession to profession.
  • Inside the directive, the values are automatically updated if changed in the controller.

Use case: Useful when passing multiple dynamic properties like user details, settings, or configuration.


Step 3: Binding Multiple Models Including Static Values

For static values, use @ binding.

Example – Binding Dynamic and Static Values

<user-info name="user.name" age="user.age" profession="user.profession" city="New York"></user-info>
app.directive('userInfo', function() {
return {
restrict: 'E',
scope: {
name: '=',
age: '=',
profession: '=',
city: '@' // One-way binding for static value
},
template: `
<div>
<h3>User Info</h3>
<p><strong>Name:</strong> {{name}}</p>
<p><strong>Age:</strong> {{age}}</p>
<p><strong>Profession:</strong> {{profession}}</p>
<p><strong>City:</strong> {{city}}</p>
</div>
`
};
});

How It Works

  • Dynamic Data (=): name, age, and profession change dynamically.
  • Static Value (@): city is passed as a string and does not change dynamically.

Use case: This is useful when you need to bind both dynamic and fixed values.


Step 4: Binding a Function with &

Sometimes, we may want to pass a function to the directive.

Example – Binding a Function with &

<user-info name="user.name" age="user.age" profession="user.profession" update="updateUser()"></user-info>
javascriptCopyEditapp.controller('MainCtrl', function($scope) {
    $scope.user = {
        name: "John Doe",
        age: 30,
        profession: "Software Engineer"
    };

    $scope.updateUser = function() {
        alert("User updated!");
    };
});

app.directive('userInfo', function() {
    return {
        restrict: 'E',
        scope: {
            name: '=',
            age: '=',
            profession: '=',
            update: '&' // Function binding
        },
        template: `
            <div>
                <h3>User Info</h3>
                <p><strong>Name:</strong> {{name}}</p>
                <p><strong>Age:</strong> {{age}}</p>
                <p><strong>Profession:</strong> {{profession}}</p>
                <button ng-click="update()">Update</button>
            </div>
        `
    };
});

How It Works

  • update="updateUser()" passes the parent function.
  • Inside the directive, calling update() triggers updateUser() in the parent scope.

Use case: Useful when the directive needs to call a function in the parent controller.


Step 5: Binding an Object Instead of Multiple Variables

If you have too many bindings, you can pass an object instead of individual variables.

Example – Binding an Object

<user-info user="user"></user-info>
app.directive('userInfo', function() {
return {
restrict: 'E',
scope: {
user: '=' // Pass the entire user object
},
template: `
<div>
<h3>User Info</h3>
<p><strong>Name:</strong> {{user.name}}</p>
<p><strong>Age:</strong> {{user.age}}</p>
<p><strong>Profession:</strong> {{user.profession}}</p>
</div>
`
};
});

How It Works

  • Instead of passing name, age, and profession separately, we pass a single object (user).
  • The directive accesses properties inside the object directly.

Use case: Ideal for large data models to avoid too many bindings.


Conclusion

Binding multiple models in an AngularJS directive enhances reusability and maintainability.

Binding TypeSyntaxUse Case
Two-way (=)name="user.name"Sync data dynamically
One-way (@)title="Admin"Pass static values
Function (&)update="updateUser()"Trigger parent functions
Object (=)user="user"Pass complex data models

Leave a Reply

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