Directives are AngularJS way of extending HTML. As the AngularJS Official documentation says, they are basically markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners).
In this detailed guide to Directives, I will try to cover every major aspect & options of Directive, including Creating Custom Directives. Since it’s a vast & very important topic, i have created a dedicated post for each one of them, so that we can really go into details if we prefer to. This will also reduce the size of this post, which will otherwise be infinite.
Let’s start. We will cover following topics, in sequence as mentioned below:
As mentioned above, Directives are essentially the markers on HTML elements. They extend HTML in following ways:
Directive are the preferred way to go if we have any of the below mentioned requirements.
AngularJS directives are created to be used as : attribute, element name, comment or CSS class. Recommended ways are as attribute & element. We will discuss this in deep details in Directive’s restrict option further down in this tutorial.
AngularJS provides several built-in directives like ng-app, ng-model, ng-repeat, ng-show, ng-class etc. We have already seen quite a few of them in previous posts. Full list is available at AngularJS Built-in Directives.
Quite often we will come to the point where built-in directives are simply not enough for our needs. In those cases, we can create custom directives. We will see how to create them in detail in this guide.
Directives are created using AngularJS module’s directive function
.
angular.module('myApp', []) .directive('itemWidget', [function() { return { //returns Directive Definition Object. // Directive definition goes here. }; }]);
First argument to the directive function is directive’s name itself. Second parameter is a factory function which is used to setup & configure our directive. This function returns an object known as Directive Definition Object. We will see the content of this object in a moment.
Once declared as above, the directive can then be used in HTML. On every use of our directive in HTML, AngularJS will look into this definition object.
By default, directive can only be used as an attribute of existing element in HTML, for example <div item-widget>. But with the help of some extra configuration (using Directive’s restrict option), we can make it to be used as independent element, like <item-widget>. We will come to that later in this tutorial.
AngularJS normalizes the name of a directive in HTML to match in JavaScript. It strips out certain prefix if they are present like [x-, data-] from directive names , and then converts (- , :, _) separated names to camelCase to match the name in javaScript. This means item-widget, Item:widget, data-item_widget or x-item-widget in HTML will all match to itemWidget in javaScript.
Directive definition object contains several key:value pairs. We will discuss each one of them in detail in this guide, starting from template/templateUrl. Based on your particular requirement, you may decide to use several key:value pairs together.
If the directive has any content that needs to be inserted when the directive is encountered, that can be done using template and templateUrl keys of the directive definition object. If the content is small, template key can be used, whereas if the content is large, templateUrl is preferable which points to the file containing actual content of directive. template & templateUrl are particularly handy for the scenario where you have some HTML that needs to be reused on multiple places in your application. Creating a directive with that content and then just simply using that directive is a nice way of HTML reuse.
Using templateUrl
Live Example:
<html> <head> <title>Directive Demo</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/> </head> <body class="jumbotron container" ng-app="myApp"> <div ng-controller="AppController as ctrl"> <h3>List of Sale Items</h3> <div ng-repeat="item in ctrl.items"> <div item-widget></div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"> </script> <script> angular.module('myApp', []) .controller('AppController', [function() { var self = this; self.items = [ {name: 'Computer', price: 500, condition:'New',brand : 'Lenovo', published:'01/11/2015'}, {name: 'Phone', price: 200, condition:'New',brand : 'Samsung', published:'02/11/2015'}, {name: 'Printer', price: 300, condition:'New',brand : 'Brother', published:'06/11/2015'}, {name: 'Dishwasher', price: 250, condition:'Second-Hand',brand : 'WhirlPool', published:'01/12/2015'}, ]; }]) .directive('itemWidget', [function() { return{ templateUrl:'saleItem.html' } }]); </script> </body> </html>
In above example, we have declared a simple directive with bare-minimum configuration. We are using only templateUrl key which points to a file [saleItem.html] containing content of directive. Then we have used this directive as an attribute of a div element within ng-repeat loop, passing items from Controller.
Below shown is the directive’s content[saleItem.html].
<div class="panel panel-default"> <div class="panel-heading"> Published at:<span ng-bind="item.published | date"></span> </div> <div class="panel-body"> Name:<span ng-bind="item.name"></span> Condition:<span ng-bind="item.condition"></span> Price:<span ng-bind="item.price | currency"></span> Brand:<span ng-bind="item.brand"></span> </div> </div>
This is a nice example of HTML reuse. Throw some CSS and you can now make your own amazon/e-bay like item list.
Using template
As mentioned above, if the directive’s content is not large, you may prefer to inline the directive content using template key instead of templateUrl. Let’s rewrite above example using template this time.
Live Example:
<html> <head> <title>Directive Demo</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/> </head> <body class="jumbotron container" ng-app="myApp"> <div ng-controller="AppController as ctrl"> <h3>List of Sale Items</h3> <div ng-repeat="item in ctrl.items"> <div item-widget></div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"> </script> <script> angular.module('myApp', []) .controller('AppController', [function() { var self = this; self.items = [ {name: 'Computer', price: 500, condition:'New',brand : 'Lenovo', published:'01/11/2015'}, {name: 'Phone', price: 200, condition:'New',brand : 'Samsung', published:'02/11/2015'}, {name: 'Printer', price: 300, condition:'New',brand : 'Brother', published:'06/11/2015'}, {name: 'Dishwasher', price: 250, condition:'Second-Hand',brand : 'WhirlPool', published:'01/12/2015'}, ]; }]) .directive('itemWidget', [function() { return{ template:'<div class="panel panel-default">'+ '<div class="panel-heading">'+ 'Published at:<span ng-bind="item.published | date"></span>'+ '</div>'+ '<div class="panel-body">'+ 'Name:<span ng-bind="item.name"></span>'+ 'Condition:<span ng-bind="item.condition"></span>'+ 'Price:<span ng-bind="item.price | currency"></span>'+ 'Brand:<span ng-bind="item.brand"></span>'+ '</div>'+ '</div>' } }]); </script> </body> </html>
As you can see, even if it does the job, in-lining large content with template key can easily become messy. First approach seems better.
That’s it for template/templateUrl configuration. Let’s move to next configuration option [restrict
] of Directive Definition Object, which helps us to decide how the directive can be used in HTML.
You can use popular Apache HTTP server to serve files. If you need assistance setting-up server,
this post can help you.
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.
In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…
Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…
Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…
Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…
Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…
This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…
View Comments
For the reason that the admin of this site is working, no uncertainty very quickly it will be renowned, due to its quality contents.
A very informative tutorial regarding AngularJS. Using such technique can make anyone's difficult task a reachable and understandable task. If given the time, I would write Ghost Professors reviews regarding this topic. Truly an eye opener.
Such an interesting topic. I start learning AngularJS, and in the begging, I got some problems, in understanding books because of difference in languages. Thanks to author of the topic A Few Tricks to Understanding the Difference between American and British English , now I can read whatever I need to make knowledge better.