While working on one of the applications being developed on the AngularJS framework, I came across a situation where I had to add a reusable and independent functionality on a DOM element. This could easily be done using JQuery. However, since the app was being developed using AngularJS, the best practice was to stick to that only, which was made easy with the AngularJS “Directive” tool.
Directive is one of the most powerful tools of AngularJS, and it includes attributes such as ng-show, ng-include, and ng-bind. In addition to this, AngularJS allows developers to define custom directives that express the application specifications and requirements much more clearly and semantically than regular HTML elements.
In the simplest terms, a directive in AngularJS is a reusable component. Directives in AngularJS encapsulate all the behavioral properties and functionalities of an element in a semantic way, thereby keeping all of the functionality grouped together. This helps to keep track of changes of one HTML section in one place rather than tracking the changes on a global level in a script.
A more formal definition of a directive is: In AngularJS, a directive is a JavaScript factory function defined inside an AngularJS module that holds a set of instructions for the HTML compiler for defining a specified behavior of a DOM element.
This section lists simple steps to define a custom directive in an AngularJS module. First, we need to define an Angular app.
var myApp = angular.module(‘myApp’, []);
Now, define a directive.
myApp.directive(‘myDirective’, function() { return { restrict: ‘E’, template: ‘<h1>I made a directive!</h1>’ }; });
This defines a directive. restrict: 'E'
means “restrict the usage of this directive to only Elements.” Thus we embed this directive in the HTML page as
<body ng-app=“myApp”> <my-directive></my-directive> </body>
This code piece is equivalent to
<body ng-app=“myApp”> <h1>I made a directive!</h1> </body>
Note that AngularJS maps the naming conventions from HTML’s my-directive
to JavaScript”s myDirective.
This is a basic example of definition and usage of a directive. The following is a more advanced example.
Consider a use case where we need an HTML structure to display movie titles. The HTML snippet looks like this:
<div class="movie"> <div class="title"> Movie Title </div> <div class="movie"> Movie name </div> </div>
The code given above seems rich in terms of CSS classes and HTML tags, but the code is not repeatable. In a case where multiple movies will need to be displayed, this code structure would become messy. Moreover, if at a later stage there comes a requirement to add a movie poster and some other functionality to the movie section, the code will need to be modified at multiple places, which is not sustainable.
Instead, we can use directive in this situation.
First, we define the Angular app and controller. Note that the list of movies is defined in the controller.
var myApp = angular.module('myApp', []); myApp.controller('myController', function($scope) { $scope.movies = ['Ice Age', 'Frozen']; });
Next, define the directive.
myApp.directive('myMovie', function() { return { restrict: 'E', transclude: 'true', template: '<span ng-transclude></span>', link: function(scope, element, attr){ element.append("<strong>"+attr.title+"</strong>"); } }; });
Now, embed the directive in the HTML code.
<div ng-app="myApp" ng-controller="myController"> <div ng-repeat="movie in movies"> <my-movie title="{{movie}}"> Movie Title : </my-movie> </div> </div>
The output is
Ta-da!
A directive is, thus, implemented as a function, which returns an object, called Data Definition Object (DDO), that configures the directive’s behavior and template. restrict, template,
etc., are the fields of this object.
restrict
: defines the type of HTML element which can act as a trigger for the directive.
transclude
: specifies whether to transfer and include the original inner content of the directive’s HTML markup (‘Movie Title :’) in the destination markup (which is defined in the template).
template
: specifies the HTML content that should be added to the HTML result of the directive.
Let’s further experiment with the directive.
movies
in the controller.$scope.movies = ['Ice Age', 'Frozen', 'Aladdin', 'Tangled', 'Cars'];
link
functionlink: function(scope, element, attr){ element.append("<strong>"+attr.title+"</strong>"); if(attr.title === 'Ice Age'){ element.append("<br> say hi to Manny!"); } else { element.append("<br> all hail the Snow Queen!"); } }
Angular provides several other fields in directive. When these fields are used in conjunction, they truly make directive perform magic on the HTML page.
Directives are useful in creating repeatable and independent code. They modularize the code by clubbing requirement-specific behavioral functions in one place, rather than creating some objects in the central controller and manipulating them using multiple JavaScript methods. Such a modular code will have multiple directives that handle their own functionalities and data, and work in isolation from other directives. As an added benefit, the HTML page and Angular scripts becomes less messy and more organized.
In this post we learned about Custom Directives in AngularJS through a brief introduction and examples of their usages and their advantages. With Directives, you can create custom HTML tags, attributes, or classes to implement required functionality over an HTML section. This then becomes an independent and reusable component that can be embedded in the same or a different HTML page.
Should we take it further? How do directives interact with the controllers? How does it access its functions and members? We’ll explore this in the next blog, which is available here!
Thank you for making it so easy to understand the concepts
Nice post Akankhsha !!!
Hi folks , I m glad to know about angular js directives .I just want to know that can it is possible in transclude we can bind the template to parent template or We can append any text,html ,string before rendering the directive into the dom .becuase here only transclude feature is mainly concern about appending while template is rendered in the dom .Is there any procedure we can provide the feasability of prepending the text .html in directive before rendering to the dom .
Thanks
Rahul Kumar
Nice post. Thanks AKANKSHA!
Hi Akanksha,
Very neat and clear example for customized directives thanks a lot for providing this
Nice Article with clear explanation.
Thank you.
good explanation..
Wonderful blog.. Thanks for sharing informative blog.. its very useful to me..
Excellent Article
{{movie}} is printed undefined, couldn’t able to pass variables in attributes, please help. Thanks.
Please check with the ng-repeat directive : ex: ng-repeat=”movie in movies”
It works fine for me…Thanks Akanksha for the nice explination:)
Actually I thing this is not sufficient to create custom directive. But your explanation and your application is good . If possible please add remaining parts to create custom directive.
should use transclude: true, instead of transclude: ‘true’,. true is a boolean and need not to use quotes.
Yeah….that is a nice catch 🙂
if you use transclude: false, it will through error
Nice article. Thanks a lot for your great work.
@Muthulakshmi, As she used “restrict: ‘E'”, so it only be used as a Element not Attribute, for that you can define “restrict: ‘EA’.
Nice explanation.
Thanks Aakansha to this tutorial. This tutorial covered very basic understanding of the custom directive.
Good explanation.
Good Explanation on directives
Good explanation. for beginner’s …
Good Explanation with example.
i am getting attr.title as undefined
Thank you so much.. this is the easiest article found on Internet regarding Custom directives… And well explained… Keep it up
Good explanation,Easily understood
Hi Aakansha,
Could you please explain more about the ‘link’ field of the object. I mean, more about link’s functions parameters in wich variable the value comes in because I have seen the example where we have more parameters such as ‘ctrl’ and we operate on that. Could you please help on this.
Thanks
Thanks Aakansha to this tutorial. This tutorial covered very basic understanding of the custom directive.
Understandable article… very nice
very clear concise and working explanation with sample code. thanks
Nice post, thanks.
I could now understand in the best possible way from this article how Angular JS makes logical separation of data & view simple. Easy to understand – such articles are needed in this complex world.
Pretty good job. It helped a lot to quickly get so much of clarity in shortest possible time! God Bless you.
The simple explanation about the custom directive.
Thanks
I have created one custom directive for our application. Everything is working fine as expected. But angular js basic attributes like ng-show, ng-hide are not working.
Very valuable post ,nicely presented the basics of custom directive ..thank you
Interesting..keep sharing.
Great Post! Keep sharing I am also looking for this kind of blog post.