AngularJS Directives: 10 Things You Need to Know
Here are a list of ten or more things which you need to know about AngularJS directives in order to get started creating your own directives and to utilize the true power of AngularJS.
1. You can make directives readonly
We can set @ for scope readonly value so that it can accept a string value instead of an object. This will be true or false to set the directive to be read only. Then the controller picks this up and disables the on click handlers for the directive.
Example:
directive.js
1 2 3 4 5 6 |
scope: { ratingValue: '=', readonly: '@' } |
ngHMTL
1 2 3 |
<div rating-value="rating" readonly="true"></div> |
controller.js (or directive.js link)
1 2 3 4 5 6 7 8 |
scope.toggle = function(index) { if(scope.readonly && scope.readonly === 'true') { return; } scope.ratingValue = index + 1; }; |
2. HTML5 Compliance
We will soon live in a world of HTML5. So make your directives and attributes HTML5 compliant. Prefix them with “data-” or “x-” so Angular will see it as a normal HTML5 element.
1 2 3 |
ie - "data-ng-show" or "x-ng-show" |
3. Controller Directive Hookup
I’ve also seen the controller being added to the element, which is probably if the elements controller changes?
1 2 3 |
<navbar ng-controller="NavbarCtrl"></navbar> |
This is redundant mostly as you can specify the controller in the directive.
1 2 3 4 5 6 7 8 9 10 11 |
angular.module("app").directive("navbar", function($location) { return { restrict: 'A', replace: true, transclude: true, templateUrl: 'partials/navbar.html', controller: 'NavbarController' } }); |
4. Declaring Directives in HTML
When declaring the directive is in camelCase and when including in HTML template it’s in hyphen lowercase.
Example
directive.js
1 2 3 4 5 6 7 |
angular.module("app").directive("footerDirective", function() { ... } |
ngHTML
1 2 3 |
<div footer-directive></div> |
5. Built-in Directives
Learn the built in directives which Angular provides out of the box.
1 2 3 |
ngHide / ngShow, ngClick, ngRepeat etc... |
6. This directive requires a function!
As directives are meant to be shared across projects. The & value tells you that the directive requires a function handler for something. This is helpful to others who are using the directive and will spit out a nice error if you omit the function.
directive.js
1 2 3 4 5 |
scope: { onRatingSelected: '&' } |
ngHTML
1 2 3 |
<div rating rating-value="rating" on-rating-selected="saveRatingToServer(newRating)"></div> |
So in the example saveRatingToServer() is the function being passed to the directive which will handle it internally or via it’s controller.
controller.js
1 2 3 4 5 |
$scope.saveRatingToServer = function(rating) { $window.alert('Rating selected - ' + rating); }; |
7. Internet Explorer doesn’t like custom HTML elements.
Restrictions to custom directives declared as elements requires extra code to get it working with IE8+.
directive.js
1 2 3 |
{ restrict: "E" } |
So it’s probably best to restrict your directives as attributes instead.
8. Syntax of directives
The tutorial of AngularJS writes directives like this: “ng-model”. But you can also write: “x-ng-model”, “ng:model”, “ng_model”, “data-ng-model”. They are all equivalent and work the same. I like to use the syntax with “data-” because it is standard-compliant.
9. Initializing your directives
There is a compile() function which can be used to specify any code to initialize your directive. On first compile Angular will run the compile function “one time” to initialize your directive with whatever code you have in the function. This is mostly useful if you cannot do the initialization inside your ngHTML template.
If the compile() function returns another function then this will be run “every time” the element is bound to data in the $scope object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
angular.module("app").directive("navbar", function($location) { return { restrict: 'E', replace: true, transclude: true, templateUrl: 'partials/navbar.html', controller: 'NavbarController', compile: function(element, attribute) { // do one time inits here return function($scope, element, attributes) { //bind element to data in scope. } } } }); |
Things to note:
- The element parameter is a jqLite wrapped jQuery DOM object.
- The attributes parameter is a JS object which contains all of the properties of the element.
10. Multiple Restricts
Did you know you can set mutiple restricts to your Angularjs directives? You can set “A”, “E” or “AE” to allow both attributes and elements for your directive.
Like this:
1 2 3 |
{ restrict: "AE" } |
I recommend however to choose just one (probably A for browser compatibility) and stick to that.