AngularJS Creating and consuming custom directives


Example

Directives are one of the most powerful features of angularjs. Custom angularjs directives are used to extend functionality of html by creating new html elements or custom attributes to provide certain behavior to an html tag.

directive.js

// Create the App module if you haven't created it yet
var demoApp= angular.module("demoApp", []);

// If you already have the app module created, comment the above line and create a reference of the app module
var demoApp = angular.module("demoApp"); 


// Create a directive using the below syntax
// Directives are used to extend the capabilities of html element 
// You can either create it as an Element/Attribute/class      
// We are creating a directive named demoDirective. Notice it is in CamelCase when we are defining the directive just like ngModel
// This directive will be activated as soon as any this element is encountered in html

demoApp.directive('demoDirective', function () {
    
  // This returns a directive definition object
  // A directive definition object is a simple JavaScript object used for configuring the directive’s behaviour,template..etc
  return {
    // restrict: 'AE', signifies that directive is Element/Attribute directive, 
    // "E" is for element, "A" is for attribute, "C" is for class, and "M" is for comment. 
    // Attributes are going to be the main ones as far as adding behaviors that get used the most.
    // If you don't specify the restrict property it will default to "A"
    restrict :'AE',  

    // The values of scope property decides how the actual scope is created and used inside a directive. These values can be either “false”, “true” or “{}”. This creates an isolate scope for the directive.
    // '@' binding is for passing strings. These strings support {{}} expressions for interpolated values.
    // '=' binding is for two-way model binding. The model in parent scope is linked to the model in the directive's isolated scope.
    // '&' binding is for passing a method into your directive's scope so that it can be called within your directive. 
    // The method is pre-bound to the directive's parent scope, and supports arguments.
    scope: { 
      name: "@",  // Always use small casing here even if it's a mix of 2-3 words
    },                  

    // template replaces the complete element with its text. 
    template: "<div>Hello {{name}}!</div>",
                
    // compile is called during application initialization. AngularJS calls it once when html page is loaded.
    compile: function(element, attributes) {
      element.css("border", "1px solid #cccccc");
                    
      // linkFunction is linked with each element with scope to get the element specific data.
      var linkFunction = function($scope, element, attributes) {
        element.html("Name: <b>"+$scope.name +"</b>");
        element.css("background-color", "#ff00ff");
      };
      return linkFunction;
    }
  };
});

This directive can then be used in App as :

<html>
   
   <head>
      <title>Angular JS Directives</title>
   </head>
   <body>
   <script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   <script src="directive.js"></script>   
    <div ng-app = "demoApp">
       <!-- Notice we are using Spinal Casing here -->  
       <demo-directive name="World"></demo-directive>
     
      </div>
   </body>
</html>