Different Kinds Of Scopes In Custom Directives

In this article I'll explain how to use different kinds of scopes in Custom Directives.

Introduction

While we create a custom directive, there is a possibility that you will want to use the scopes available in the parent controller. You can use the scopes of the parent controller  in different levels. This article will help you choose in between those levels.

I created a sample application which will help you understand it in an easy manner.

Step 1

Firstly, I added a HTML page where our custom control is created.

  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4.     <title></title>  
  5.     <script src="angular.js"></script>  
  6.     <script src="AngularScript.js"></script>  
  7. </head>  
  8. <body ng-app="angularApp">  
  9.     <form ng-controller="angularController">  
  10.         <fieldset>  
  11.             <legend>I am binding from controller  
  12.             </legend>  
  13.             <input type="text" ng-model="EnterName" />  
  14.         </fieldset>  
  15.   
  16.         <br />  
  17.         <fieldset>  
  18.             <legend>I am binding from directive  
  19.             </legend>  
  20.             <custom-directive></custom-directive>  
  21.         </fieldset>  
  22.     </form>  
  23.   
  24. </body>  
  25. </html>  

In this code you can see I had bound the form tag with a controller named "angularController," this controller will be created in upcoming steps.

In this form I used two fieldsets to distinguish between normal controller binding and custom directive. In the first fieldset I created an input control which is bound to a model named "EnterName." 

In the second fieldset I created a custom control named "custom-directive," using this control I'll create the custom directive.

Step 2

Now it's time to work on the angular part. I added a JavaScript file to my application in which I had written my angular code.

Firstly, I created a module and a controller.

  1. var angularApp = angular.module('angularApp', []);  

  2. angularApp.controller('angularController', function ($scope) {  
  3.     $scope.EnterName = "Anubhav";  
  4. });  

Now it's time to create our custom directive, but before creating it, let's first know how scopes will be used in this directive or what level will be used here.

scope : false

So, in this directive you will be able to access the scopes completely without having any kind of restriction. Let's first see the code and after that I'll explain it.

  1. angularApp.directive("customDirective"function () {  
  2.     return {  
  3.         restrict: "E",  
  4.         scope: false,  
  5.         template: "<div>Name you Entered is : {{EnterName}}</div>" +  
  6.             "Provide Your Name : <input type='text' ng-model='EnterName' />"  
  7.         };  
  8. });  

You can see that I wrote "scope : false," it means custom directive will not have its own new scope and it'll inherit its parent scope completely. So whatever model you have defined in your controller can be easily used here, just as I have used in the template. One more important thing with "scope : false" is that if you make changes in scope data then that will be reflected in both controller and in directive as well.

Let's see the output to clearly understand it.


You can see that both the textboxes and label have the predefined data, now if I change the data in any of the textbox then changes will occur in all the controls which are bound to this model.


scope : true

It might be possible that you want to use the value of parent scopes for one time only i.e. at initial stage but after that you don't want your directive scope to get updated if there is a change at parent scope or vice versa, then in that case just provide "scope : true."

  1. angularApp.directive("customDirective"function () {  
  2.     return {  
  3.         restrict: "E",  
  4.         scope: true,  
  5.         template: "<div>Name you Entered is : {{EnterName}}</div>" +  
  6.             "Provide Your Name : <input type='text' ng-model='EnterName' />"  
  7.         };  
  8. });  

Now let's again run the application and check what is happening.


As the page loads all the controls get their initial value which was predefined in the controller, but if I change the data in second textbox i.e. at custom directive level, then only those controls will get updated which are created using custom directive and everyone else will remain the same.


scope : { }

Scope :true was providing you a new scope but after the initial level, what if you do not want any kind of interference between controller and directive i.e. you do not want to use any value from controller? Therefore, in that case make isolated scope i.e. "scope : {}"

  1. var angularApp = angular.module('angularApp', []);  

  2. angularApp.controller('angularController'function ($scope) {  
  3.     $scope.EnterName = "Anubhav";  
  4. });
  5.   
  6. angularApp.directive("customDirective"function () {  
  7.     return {  
  8.         restrict: "E",  
  9.         scope: {},  
  10.         template: "<div>Name you Entered is : {{EnterName}}</div>" +  
  11.             "Provide Your Name : <input type='text' ng-model='EnterName' />"  
  12.         };  
  13. });  

You can see that still in the template I bound the controls with the same model to which they were earlier bound but now this model will not have any impact from previous one because they are defined in a new scenario.

Let's again run the application and check what's happening.


You can see that only first textbox is getting the value but our label and second textbox is empty. But if I try to write any value in the second textbox then label also get updated because it's bound to the same model to which second textbox is bound.


Isolated scopes is a new topic in itself and I'll explain it in my next article.