Tuesday, September 30, 2014

AngularJS for Beginners: Custom Directive: Part II

Isolate Scope
In AngularJS applications, parent scope is accessible to the directives by default. We cannot make reusable directives by using the parent scope only. We need a separate scope inside the directive, and there should be a way to map the directive's inner scope with the outer scope or parent scope. We can do this by using the isolate scope.

Creating Isolate Scope
We can create isolate scope in a directive simply by adding a scope property into the directive. This will isolate the directive’s scope from the parent scope.
 myModule.directive('myBook', function() {   
      return {  
           scope: {       
           },  
           template: 'Name: {{name}}<br> Author: {{author}}'  
      };   
 });  
The scope has become isolated now. The parent scope is no longer accessible.

Local Scope Properties
Directives having isolate scope can interact with the parent scope in 3 different ways. These 3 options are called Local Scope Properties. These properties can be used by using  @, = and & characters.

'@' Local Scope Property
To access string values from parent scope, we can use the '@' local scope property. For example, our controller has a name property on the $scope object and we need to access that property from our directive. '@' local scope property allows one-way data binding. Any change in parent scope will be reflected on local scope. But, change in local scope will not be reflected on parent scope.
Here is an example of '@' local scope:
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">   
           <div my-book name="{{ name }}" author="{{ author }}" ></div>   
      </div>   
      <script>        
           var myModule = angular.module("myModule", []);   
           myModule.controller('BooksController',    
           function BooksController($scope) {    
                $scope.name = 'The Tempest';  
                $scope.author = 'William Shakespeare';  
           });   
           myModule.directive('myBook', function() {   
                return {  
                     scope: {  
                          name: '@',  
                          author: '@'            
                     },  
                     template: 'Name: {{name}}<br> Author: {{author}}'  
                };   
           });                  
       </script>  
 </body>  
 </html>  
Online demo of the above example can be found in Plnkr.co

'=' Local Scope Property
If we want to allow two-way binding between the parent scope and the directive’s isolate scope we have to use the '=' local scope property.
Here is an example of '=' local scope:
  <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">   
           <div my-book book="book"></div>   
      </div>   
      <script>        
           var myModule = angular.module("myModule", []);   
           myModule.controller('BooksController',    
           function BooksController($scope) {   
                $scope.book = {   
                     name:'The Tempest',    
                     author:'William Shakespeare'   
                };   
           });   
           myModule.directive('myBook', function() {   
                return {  
                     scope: {  
                          book: '=' //Two-way data binding  
                     },  
                     template: 'Name: {{book.name}}<br>'+  
                          'Author: {{book.author}}'  
                };   
           });                  
       </script>  
 </body>  
 </html>  
Online demo of the above example can be found in Plnkr.co

'&' Local Scope Property
If we want to pass a parent scope's function instead of data into a directive, we have to use '&' local scope. Directive can invoke the function whenever it is required.
Here is an example of '&' local scope:
  <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">   
           <div my-book   
                book="book"   
                action="changeData()">  
           </div>  
      </div>   
      <script>        
           var myModule = angular.module("myModule", []);   
           myModule.controller('BooksController',    
           function BooksController($scope) {       
                $scope.book = {   
                     name:'The Tempest',    
                     author:'William Shakespeare'   
                };   
                $scope.changeData = function () {  
                     $scope.book = {  
                          name: 'Gitanjali',  
                          author: 'Rabindranath Tagore'  
                     };  
                };  
           });   
           myModule.directive('myBook', function () {  
                return {  
                     scope: {  
                          book: '=',  
                          action: '&'  
                     },  
                     template: 'Name: {{book.name}}<br>'+  
                          'Author: {{book.author}}<br>' +  
                          '<button ng-click="action()">' +  
                          'Change Data</button>'  
                };  
           });                  
       </script>  
 </body>  
 </html>  
Here, the changeData() function of parent scope is passed into our directive. The function is invoked in the directive through a click event later. Online demo of the above example can be found in Plnkr.co

Manipulate DOM using Link function
The link function is used in directive to manipulate the DOM. The link function takes three parameters: The $scope parameter, the element parameter and the attributes parameter.
  • The $scope parameter is a normal or isolate scope object.
  • The element parameter is a jqLite wrapped DOM element that the target directive matches. (For DOM manipulation, AngularJS contains a lite version of jQuery)
  • The attributes parameter is a JavaScript object containing all the attributes of the target HTML element.
Here is a complete example of using link function:
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
     <div ng-controller="BooksController">   
         <div my-book book="book"></div>  
     </div>   
       
     <script>       
         var myModule = angular.module("myModule", []);   
         myModule.controller('BooksController',    
         function BooksController($scope) {      
             $scope.book = {   
                 name:'The Tempest',    
                 author:'William Shakespeare'   
             };   
               
         });   
           
         myModule.directive('myBook', function () {  
         return {  
             scope: {  
                 book: '='  
             },  
             template:   
                 'Name: {{book.name}}, Author: {{book.author}}',  
             link:   
                 function ($scope, element, attrs) {  
                     element.bind('click', function () {  
                         element.html('You clicked the book: '  
                             + $scope.book.name);  
                     });  
                     element.bind('mouseenter', function () {  
                         element.css('color', 'yellow');  
                         element.css('background-color', 'blue');  
                     });  
                     element.bind('mouseleave', function () {  
                         element.css('color', 'white');  
                         element.css('background-color', 'black');  
                     });  
                 }      
         };  
         });               
      </script>  
 </body>  
 </html>  
In the above example, style or content of the target HTML element has been changed by using link function. Online demo of the above example can be found in Plnkr.co

[TOC]    << Previous    Next >>