Scaffold your ideas into application
Get your free alpha access now.
Only 445 left, Hurry!
21 Nov 2016

Angular Directives Demystified

directives

In angular world, directives are means to extend HTML by defining new tags and attributes. Imagine if you had a <calendar></calendar> tag instead of using JQuery $('input.calendar').calendar().

angular.directive('calendar',function(){
    return{
        restrict:'E',
        template:'<div class="calendar>
        ...
        </div>'
    }
});

Above code would render a calendar any time angular encounters a <calendar></calendar> tag in your HTML. Lets see in details how directives work and what all can be done using directives.

The above example simply replaces the html fragment in variable template where ever our calendar tag is found. You can use templateUrl to load an external template instead of inline template. That seems cool, but how about if you want to have nested elements inside your directives. like following

<calendar>
  <span>Awesome Calendar</span>
</calendar>

In such a case you would use a feature of angular called transclude, this ways you can have the html fragment defined in your tempate variable wrap around the inside code.

angular.directive('calendar',function(){
    return{
      restrict:'E',
      transclude:true,
      template: '<div class="calendar">' +
      '<div ng-transclude></div>' +
      '</div>'
    }
});

You can see the above code at Plunker

Lets look at the lifecycle of directive to understand the magic which goes in here.


angular.directive('calendar',function(){
  return{
      restrict:'E',
      compile: function (elem,attr) {
        return {
          pre: function($scope,elem,attr){

          },
          post:function ($scope,elem,attr) {

          }
        }
      }
      //or
      link: {
          pre: function($scope,elem,attr){

          },
          post:function ($scope,elem,attr) {

          }
      }
  }
});

Remember do not use link and compile with pre and post together, it wont work

So when do you use compile and when do use link function. In most of the cases, you would be using only one link function which is defaulted to post link function like following.

angular.directive('calendar',function(){
  return{
      restrict:'E',
      link:function($scope,elem,attr){
          $(elem).calendar();
      }
    }
  });

You would use compile function, in case you need to change the template which is loaded before angular processes it or may be generate a template on the fly.

link function is called before the generated HTML is appended to the existing DOM, so if you need to initialize any plugin, link is the best place to do that.

Remember that if there is a controller function attached to the directive, it would be called before link function is executed.

Scope Isolation

Unlike scope in controller, the directive have much more control on how scope gets created and is assigned to the directive. This is controller by the scope declaration in directive.

angular.directive('calendar',function(){
  return{
      restrict:'E',
      scope:true/false,
    }
  });

If the scope is set to true, then a new child scope is created from current scope and is assigned to the directive.

If the scope is set to false, then the current scope is passed to the directive. This is beneficial if you want to access and modify more than few properties of parent scope. Any changes made to scope in directive would apply to the parent view as well.

The third and a little confusing options is isolated scope, which is represented by {} for scope. An isolated scope is independent of the parent scope and does not inherit or access the parent scope in any way. If you are making any reusable component, make sure that they depend on isolated scope and not on access to parent scope as earlier options depends on the hierarchy of DOM for access.

If you need to allow some access to isolated scope, it can be done via =, & or @.

angular.directive('calendar',function(){
  return{
      restrict:'E',
      scope:{
      title:'@',
      date:'=',
      validate:'&'
      },
    }
  });
<calendar title="{{title}}" date="date" validate="isValid()"></calendar>

Using @ allows access to variables via attributes. If we change title in the directive, there will be no effect to the title variable in parent scope.

Using = allows access to variable via attribute but has a two way binding, so any change to date would reflect in the parent scope as well.

Using & allows access to methods in parent scope, which can be executed in the directives.

In the next part we would talk about event management in angular.


Stats:
76 views
Scaffold your ideas into application
Get your free alpha access now.
Only 445 left, Hurry!

Third wave of digital transformation

Third wave of digital transformation

Angularjs Tutorial: Understanding Scope

Scopes are one of the most important and rarely understood concept in angular, in this part we explore how scope works in angularjs.

Angularjs Tutorial: Basics

This article covers the basic fundamental concept of Angular JS

Comments:

Leave your comments