A custom directive in Angular Js is a user-defined directive with your desired functionality. Even though AngularJS has a lot of powerful directives out of the box, sometime custom directives are required.
In this tutorial, you will learn-
Let's take a look at an example of how we can create a custom directive.
The custom directive in our case is simply going to inject a div tag which has the text "AngularJS Tutorial" in our page when the directive is called.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <div ng-guru=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('ngGuru',function(){ return { template: '<div>Angular JS Tutorial</div>' } }); </script> </body> </html>
Code Explanation:
Note:-
Note that when defining the directive, we have defined it as ngGuru with the letter 'G' as capital. And when we access it from our div tag as a directive we are accessing it as ng-guru. This is how angular understands custom directives defined in an application. Firstly the name of the custom directive should start with the letters 'ng'. Secondly the hyphen symbol '-' should only be mentioned when calling the directive. And thirdly the first letter following the letters 'ng' when defining the directive can be either lower or uppercase.
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
The scope is defined as the glue which binds the controller to the view by managing the data between the view and the controller.
When creating custom AngularJs directives, they by default will have access to the scope object in the parent controller.
In this way, it becomes easy for the custom directive to make use of the data being passed to the main controller.
Let's look at an example of how we can use the scope of a parent controller in our custom directive.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp" ng-controller="DemoController"> <div ng-guru=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.controller('DemoController',function($scope) { $scope.tutorialName = "Angular JS"; }); app.directive('ngGuru',function(){ return { template: '<div>{{tutorialName}}</div>' } }); </script> </body> </html>
Code Explanation:
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
Angular gives the facility to access the controller's member variable directly from custom directives without the need of the scope object.
This becomes necessary at times because in an application you may have multiple scope objects belonging to multiple controllers.
So there is a high chance that you could make the mistake of accessing the scope object of the wrong controller.
In such scenario's there is a way to specifically mention saying "I want to access this specific controller" from my directive.
Let's take a look at an example of how we can achieve this.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp" ng-controller="DemoController"> <div ng-guru99=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.controller('DemoController',function() { this.tutorialName = "Angular"; }); app.directive('ngGuru99',function(){ return { controller: 'DemoController', controllerAs: 'ctrl', template: '{{ctrl.tutorialName}}' }; }); </script> </body> </html>
Code Explanation:
Note: -It is possible to access multiple controllers in a directive by specifying respective blocks of the controller, controllerAs and template statements.
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
The output clearly shows that the custom directive is especially accessing the DemoController and the member variable tutorialName attached to it and displays the text "Angular".
We already saw the power of custom directives, but we can take that to the next level by building our own re-usable directives.
Let's say, for example, that we wanted to inject code that would always show the below HTML tags across multiple screens, which is basically just an input for the "Name" and "age" of the user.
To reuse this function on multiple screens without coding each time, we create a master control or directive in angular to hold these controls ("Name" and "age" of the user).
So now, instead of entering the same code for the below screen every time, we can actually embed this code in a directive and embed that directive at any point in time.
Let' see an example of how we can achieve this.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <div ng-guru=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('ngGuru',function(){ return { template: ' Name <input type="text"><br><br> Age<input type="text">' }; }); </script> </body> </html>
Code Explanation:
Instead of a plan five tag or text, we are actually entering the entire fragment of 2 input controls for the "Name" and "age" which needs to be shown on our page.
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
From the above output, we can see that the code snippet from the template of the custom directive gets added to the page.
As we mentioned quite earlier, Angular is meant to extend the functionality of HTML. And we have already seen how we can have code injection by using custom re-usable directives.
But in the modern web application development, there is also a concept of developing web components. Which basically means creating our own HTML tags that can be used as components in our code.
Hence angular provides another level of power to extending HTML tags by giving the ability to inject attributes into the HTML tags itself.
This is done by the "ng-transclude" tag, which is a kind of setting to tell angular to capture everything that is put inside the directive in the markup.
Let's take an example of how we can achieve this.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <pane title="{{title}}">Angular JS</pane> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('pane',function(){ return { transclude:true, scope :{title:'@'}, template: '<div style="border: 1px solid black;"> '+ '<ng-transclude></ng-transclude>'+ '</div>' }; }); </script> </body> </html>
Code Explanation:
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
Directives in angular can be nested. Like just inner modules or functions in any programming language, you may need to embed directives within each other.
You can get a better understanding of this by seeing the below example.
In this example, we are creating 2 directives called "outer" and "inner".
</head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <outer></outer> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('outer',function(){ return { restrict:'E', template: '<div><h1>Outer</h1><inner></inner></div>', }}); app.directive('inner',function(){ return { restrict:'E', template: '<div><h1>Inner</h1></div>', } }); </script> </body> </html>
Code Explanation:
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
From the output,
Events such mouse clicks or button clicks can be handled from within directives itself. This is done using the link function. The link function is what allows the directive to attach itself to the DOM elements in an HTML page.
Syntax:
The syntax of the link element is as shown below
ng-repeat
link: function ($scope, element, attrs)
The link function normally accepts 3 parameters including the scope, the element that the directive is associated with, and the attributes of the target element.
Let's look at an example of how we can accomplish this.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <div ng-guru="">Click Me</div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('ngGuru',function(){ return { link:function($scope,element,attrs) { element.bind('click',function () { element.html('You clicked me'); });} }}); </script> </body> </html>
Code Explanation:
If the code is executed successfully, the following Output will be shown when you run your code in the browser.
Output:
Summary