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 >>

Sunday, August 31, 2014

AngularJS for Beginners: Custom Directive: Part I

What is Directive
Directive is a kind of method of AngularJS to create new HTML elements or to add custom functionality to HTML elements. Directives can be considered as markers on a DOM element (attribute, element name, comment or CSS class) which enable compiler of AngularJS to attach a specified behavior to that DOM element or to transform the DOM element and its children. 

Angular comes with a set of built-in directives such as ng-bind, ng-model and ng-view etc. We can also create custom directives of our own.

How to create custom directive
We use Angular module’s directive method to create custom directive. Using the directive method, we can register a new directive by providing the name of directive as string and a function. The name of the directive should always be in camelCase form, and the function we should return an object. Here is a simple example:
 var myModule = angular.module("myModule", []);  
 myModule.controller('BooksController',   
 function BooksController($scope) {  
      $scope.book = {  
           name:'The Tempest',   
           author:'William Shakespeare'  
      };  
 });  
 myModule.directive('myBook', function() {  
      return {  
           template: 'Name: {{book.name}}<br>Author: {{book.author}}'  
      };  
 });  
Here we have created a simple directive that replaces its contents with a static template. We have used the template attribute to do it. We can use that directive in HTML like the following:
 <div ng-controller="BooksController">  
      <div my-book></div>  
 </div>  
In HTML, we have to use the dash-delimited lower-case form of the name of directive. In our case, myBook has to be used as my-book in HTML.

The template and templateUrl Properties
The HTML template can grow bigger. It is difficult to maintain larger HTML template inside a single JavaScript string. We can put the HTML template in a separate file and make AngularJS load it from the file. We can do it by using the templateUrl property. Here is an example:
 var myModule = angular.module("myModule", []);   
 myModule.controller('BooksController',    
 function BooksController($scope) {   
      $scope.book = {   
           name:'The Tempest',    
           author:'William Shakespeare'   
      };   
 });   
 myModule.directive('myBook', function() {   
      return {   
           templateUrl: 'my-template.html'   
      };   
 });  
AngularJS will load the HTML template from the URL provided in the templateUrl property. Here, my-template.html page will contain the code like:
 Name: {{book.name}}<br>Author: {{book.author}}  
Unless our template is very small, it is best practice to keep the HTML template in a separate HTML file and load it using the templateUrl property.

Properties of Directive
We can use several properties to define a custom directive. The other most commonly used properties are:
  • restrict
  • scope
  • template
  • templateUrl
  • link
We have already discussed about template and templateUrl properties. We will discuss scope and link in the next post. Now, let's know about the restrict property.
The restrict property determines how the directive will be activated or triggered. There are 4 types of restrict properties:
  • 'A' - matches attribute name
  • 'E' - matches element name
  • 'C' - matches CSS class name
  • 'M' - matches comment name
Several restrictions can be used simultaneously by using them in combined form:
'AEC' - matches either attribute or element or class name

Let's apply restrict property to our directive and change to match by element name:
 var myModule = angular.module("myModule", []);   
 myModule.controller('BooksController',    
 function BooksController($scope) {   
      $scope.book = {   
           name:'The Tempest',    
           author:'William Shakespeare'   
      };   
 });   
 myModule.directive('myBook', function() {   
      return {  
           restrict: 'E',   
           templateUrl: 'my-template.html'   
      };   
 });  
We have to use that directive in HTML now by using tag name <my-book> like the following:
 <div ng-controller="BooksController">   
      <my-book></my-book>   
 </div>  


Tuesday, July 22, 2014

AngularJS for Beginners: Custom Filter

Filter
Angular filters provide a way to format the data that we display to the user or we use in our app. There are several built-in filters. We can also create filter of our own.

How to create custom filter
We use Angular module’s filter method to create custom filter. It is best practice to create a separate module for declaring the filters. Let's create a simple filter to capitalize all the characters of a string.
 var myFilters = angular.module('myApp.filters', []);  
 myFilters.filter('makeUppercase', function () {  
      return function (input) {  
           if (input) {  
                return item.toUpperCase();  
           }  
      };  
 });  
Filter is basically a kind of function to which we pass single or multiple inputs. In the above example, we take a single input string. Filtering operations are applied on the input.

Using a consecutive filter method, we can create another filter. Let's create another filter to replace space characters with underscores.
 var myFilters = angular.module('myApp.filters', []);  
 myFilters.filter('makeUppercase', function () {  
      return function (input) {  
           if (input) {  
                return item.toUpperCase();  
           }  
      };  
 })  
 .filter('underscore', function () {  
      return function (input) {  
           if (input) {  
                return input.toLowerCase().replace(/[^a-z_]/g, '_');  
           }  
      };  
 });  

How to invoke
Filters can be invoked from either HTML or JavaScript. In HTML, filters are invoked by using the pipe ( | ) character inside the template binding characters {{ }}. Multiple filters can be applied to same expression. We can apply the 'makeUppercase' filter in the following way:
      {{ book.name | makeUppercase }}  
Applying both 'makeUppercase' and 'underscore' filters, the expression will look like the following:
      {{ book.name | underscore | makeUppercase }}  
Filters can be used from JavaScript by using the $filter service. We have to inject $filter as a dependency into our controller in order to invoke our filter. At the time of calling the filter, we can pass both the filter name and data as arguments. The following example shows how 'makeUppercase' and 'underscore' filters can be used from JavaScript:
 myModule.controller('BooksController',   
      function BooksController($scope, $filter) {  
           var bookname = 'The Mother';  
           var bookname = $filter('underscore')(bookname);       
           $scope.bookName = $filter('makeUppercase')(bookname);                 
      }  
 );  

Complete example
Here is the complete example:
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">  
           <br>  
           List of books:  
           <br>                  
           <ul>  
                <li ng-repeat="book in bookList">  
                     {{book.name | underscore | makeUppercase }}   
                     -- {{book.author}}   
                </li>  
           </ul>  
           Book name: <input type="text" ng-model="bookName" />  
           Author: <input type="text" ng-model="bookAuthor" /> <br>  
           <button ng-click="add()">Add</button>  
      </div>  
        
      <script>        
           var myFilters = angular.module('myApp.filters', []);  
           myFilters.filter('makeUppercase', function () {  
                return function (input) {  
                     if (input) {  
                          return input.toUpperCase();  
                     }  
                };  
           })  
           .filter('underscore', function () {  
                return function (input) {  
                     var inputLower = input.toLowerCase();  
                     return inputLower.replace(/[^a-z_]/g, '_');                      
                };  
           });  
                       
           var myModule = angular.module('myModule', ['myApp.filters']);       
           myModule.controller('BooksController',   
           function BooksController($scope) {  
                $scope.bookList = [  
                     {name:'The Tempest',   
                          author:'William Shakespeare'},  
                     {name:'Gitanjali',   
                          author:'Rabindranath Tagore'},  
                     {name:'Harry Potter',   
                          author:'J. K. Rowling'},  
                     {name:'The Da Vinci Code',   
                          author:'Dan Brown'},  
                     {name:'A Brief History of Time',   
                          author:'Stephen Hawking'},  
                     {name:'Tell Me Your Dreams',   
                          author:'Sidney Sheldon'}  
                ];  
                  
                $scope.add = function() {  
                     $scope.bookList.push({   
                          name: $scope.bookName,   
                          author: $scope.bookAuthor   
                     });  
                };  
           });       
       </script>  
 </body>  
 </html>  
We should see something like the following in the browser:





Monday, June 30, 2014

AngularJS for Beginners: Route


Route
AngularJS has a robust routing mechanism. It supports hash-based routing. A template mechanism called "layout template" is used for routing. We break out the view into a layout template and partial view templates. The layout template is common for all views. The partial templates are included into this layout template depending on the current "route" - the view that is currently displayed to the user.

Routes in AngularJS are declared using the $routeProvider, which is the provider of the $route service. This service makes it easy to wire together controllers, view templates, and the current URL location in the browser.

Installation
In order to use routes in our AngularJS app, we have to install and reference it in our app. We can download it from https://code.angularjs.org and save it in a place that we can reference it from our HTML. The reference of angular-route must be followed by the reference of AngularJS itself.
 <script src="angular.min.js"></script>  
 <script src="angular-route.js"></script>  
We have to reference the ngRoute module as a dependency in our app module:
  var myModule = angular.module('myModule', ['ngRoute']);
Layout template using ng-view
To make a layout template, we have to tell AngularJS where to render the template. Using the ng-view directive in conjunction with the $route service, we can specify exactly where in the DOM we want to place the rendered view template of the current route. The role of the ng-view directive is to include the rendered view template for the current route into the layout template.  Each time the current route changes, the included view changes with it according to the configuration of the $route service.

Look at the following code snippet of a layout template:
  <header>  
      <h1>Header</h1>  
 </header>  
 <div class="content">  
      <div ng-view></div>  
 </div>  
 <footer>  
      <h2>Footer</h2>  
 </footer>  
In this case, we are placing all of the rendered content in the <div class="content">, more specifically in the <div> containing the ng-view directive. Other elements like <header> and <footer> will not be affected due to route changes.

Routes
We use Angular module’s config method to create route. Two methods of $routeProvider are used for declaring route: the when method and the otherwise method.  See the following code snippet:
 var myModule = angular.module('myModule', ['ngRoute']);            
 myModule.config(function ($routeProvider) {                 
      $routeProvider  
           .when('/view1', {  
                controller: 'BooksController',  
                templateUrl: 'View1.html'  
           })  
           .when('/view2', {  
                controller: 'BooksController',  
                templateUrl: 'View2.html'  
           })       
           .otherwise({   
                redirectTo: '/view1'   
           });                      
 });       
To add a new route definition to the $route service, the when method is used. This method takes two parameters (when(path, route)). The first parameter is the route path, which is matched against the path of the current URL i.e. the $location.path. The second parameter is the configuration object, which determines what should be done if the route in the first parameter is matched. In the configuration object, we can set properties like controller, template, templateURL, resolve, redirectTo etc. In the above example, we used templateUrl and controller.     

If the templateUrl property is set, path or function that returns a path to an html template that should be used by ngView.

If we set the controller property on the configuration object, the controller given will be associated with the new scope of the route.

When no other route definition is matched, the otherwise method provides route definition that will be used for changing route.

resolve
If we set the resolve property, an optional map of dependencies will be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. See the following code snippet:
 resolve: {  
      'dataMap': ['$http', function($http) {  
           return $http.get('/api').then(  
                function success(resp) { return response.data; }  
                function error(reason) { return false; }  
           );  
      }]  
 }  
In the above example, resolve sends the $http request off and fills the value of ‘data-map’ as the result of the request. The ‘dataMap’ key of the map above will be injected into our controller, so it can be retrieved in the controller. 

$routeParams
We can store parameter in the URL by the name of the parameter with a colon before it (for example, :bookId). The $routeParams service allows you to retrieve the current set of route parameters. Let us set up a route like the following:
 $routeProvider  
      .when('/view1/:bookId', {  
           controller: 'BooksController',  
           templateUrl: 'View1.html'  
      })  
Now, AngularJS will populate the $routeParams with the key of :bookId, and the value of key will be populated with the value of the loaded URL. If the URL /view1/101 is loaded in the browser, then the $routeParams object will look like:
 { bookId: '101' }  
In order to access to these variables in the controller, we need to inject the $routeParams in the controller:
 myModule.controller('BooksController', function($scope, $routeParams) {  
      // $routeParams can be accessed from here  
 });  
Full Example
Here is a full example of route. Three separate html files are used in this example: first one (routeExample.html) for layout template and defining route and others (View1.html and View2.html) for partial template views.

routeExample.html
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
       <script src="angular-route.js"></script>  
 </head>  
 <body>  
      <div id="container">  
           <div ng-view=""></div>  
      </div>  
        
      <script>                  
           var myModule = angular.module('myModule', ['ngRoute']);                 
             
           // set route provider  
           myModule.config(function ($routeProvider) {                 
                $routeProvider  
                     .when('/view1', {  
                          controller: 'BooksController',  
                          templateUrl: 'View1.html'  
                     })  
                     .when('/view2', {  
                          controller: 'BooksController',  
                          templateUrl: 'View2.html'  
                     })       
                     .otherwise({   
                          redirectTo: '/view1'   
                     });                      
           });            
        
        
           myModule.factory('myService', function () {  
                var bookList = [  
                     {name:'The Tempest',   
                          author:'William Shakespeare'},  
                     {name:'Gitanjali',   
                          author:'Rabindranath Tagore'},  
                     {name:'Harry Potter',   
                          author:'J. K. Rowling'},  
                     {name:'The Da Vinci Code',   
                          author:'Dan Brown'},  
                     {name:'A Brief History of Time',   
                          author:'Stephen Hawking'},  
                     {name:'Tell Me Your Dreams',   
                          author:'Sidney Sheldon'}  
                ];  
                  
                var serviceInstance = {};  
                  
                serviceInstance.getBooks = function () {  
                     return bookList;  
                };  
                  
                serviceInstance.addBook =   
                     function (bookName, bookAuthor) {  
                          bookList.push({   
                               name: bookName,   
                               author: bookAuthor   
                          });  
                     };  
                  
                return serviceInstance;                 
           });            
             
             
           myModule.controller('BooksController',   
                function BooksController($scope, myService) {  
             
                     $scope.bookList = myService.getBooks();  
                  
                     $scope.add = function() {  
                          myService.addBook(  
                               $scope.bookName,   
                               $scope.bookAuthor  
                          );  
                     };  
           });                      
       </script>  
 </body>  
 </html>  
View1.html
 <div>  
      <h1>  
           View 1 loaded  
      </h1>  
      <br>  
      List of books:  
      <br>                  
      <ul>  
           <li ng-repeat="book in bookList">  
                {{book.name}} -- {{book.author | uppercase}}   
           </li>  
      </ul>  
      Book name: <input type="text" ng-model="bookName" />  
      Author: <input type="text" ng-model="bookAuthor" /> <br>  
      <button ng-click="add()">Add</button>  
      <br><br>  
      <a href="#/view2">Load view 2</a>  
 </div>  
View2.html
 <div>  
      <h1>  
           View 2 loaded  
      </h1>  
   
      <ul>  
           <li ng-repeat="book in bookList">  
                {{book.name}} -- {{book.author | uppercase}}   
           </li>  
      </ul>  
      <br>  
      <a href="#/view1">Load view 1</a>  
 </div>  
The browser should display the following output:



Clicking the link below will show the following:




Monday, May 26, 2014

AngularJS for Beginners: Service


What is Service?
Service is a simple object that can do some specific tasks. Angular service is stateless in general. Since having properties indicates some sort of state, the public members of a service should be functions instead of properties. Each service encapsulates some sort of functionality or contains some business logic.

Services are singleton objects. It means they are instantiated only once for an app. Services are lazy loaded (created only when necessary). So, service is a stateless singleton object that contains some useful functions. Components like Controllers, Directive and Filters etc. can use the functions of a service.

Why Service is used
Services follow two important object oriented design principles: 1. Single Responsibility Principle (SRP) and 2. Dependency Inversion Principle (DIP).

The Single Responsibility Principle states that every object should have a single responsibility. We can use the example of a controller here. The responsibility of a controller is to bind model data to views using the scope. It should not contain the logic to fetch or update the data. If a controller is also responsible for fetching and updating data, this is the violation of the SRP principle. Data fetching or manipulation logic or any other business logic should be implemented in a separate service. That service can be injected into a controller or any other component afterwards.

Dependency Injection follows the Dependency Inversion Principle. The DIP states that objects should depend on abstractions, not concretions. In JavaScript, we can consider any parameter of a function (constructor function or other) as an abstraction because any object can be passed in for that parameter. This is how dependency injection is used in AngularJS. The controllers, directives, filters and other services can take in any external dependencies (i.e. services) as parameters during construction. This makes the code loosely coupled and each component becomes more manageable and testable.  

How Service is created
There are five different Angular module’s methods for creating custom services:
  • factory()
  • service()
  • constant()
  • value()
  • provider()
I will cover the first two of them.

Factory method:
The most common and quick way to create a custom service is to use the module’s factory method:
 var myModule = angular.module('myModule', []);  
 myModule.factory('myService', function() {  
   var serviceInstance = {}; 
 
   // .................  

   return serviceInstance;  
 });  
In the above code, we have created a custom service named ‘myService’. The first parameter of the factory method represents the name our service, and the second parameter represents a function. The object ‘serviceInstance’ returned by that function will become our custom service. In this example, an empty object is returned, so our service does not do anything now. However, it is now registered with the AngularJS app using the name ‘myService’. Let’s add some functionality to our service:
 var myModule = angular.module('myModule', []);  
 myModule.factory('myService', function() {  
   var serviceInstance = {}; 
 
   serviceInstance.task1 = function() {  
      // ..............  
   }  

   serviceInstance.task2 = function() {  
      // ..............   
   } 
 
   return serviceInstance;   
 });  

Service method:
If we want to create a custom service using a constructor function, we can use module’s service method:
 var myModule = angular.module('myModule', []);  
 myModule.service('myService', function() { 
 
   this.task1 = function() {  
      // ..............  
   }  

   this.task2 = function() {  
      // ..............   
   }  

 });  
In the above code, we have created a custom service named ‘myService’. The first parameter of the service method represents the name our service, and the second parameter represents the constructor function. The service method will use the new keyword when the service instance will be created. The keyword this is used to define the functions of our service here.

How service is used
If we want to use a service for a component, we have to identify it as a dependency for that component. Here a component can be a controller, a directive, a filter or another service. All we have to do is to inject the service by adding it as a parameter in the definition of the component.

To inject a service in a controller, we have to pass the name of the service as a parameter to the controller function:
 var myModule = angular.module('myModule', []);  
 myModule.controller('myController', function($scope, myService) {  
   myService.task1();  
   myService.task2();       
 }  
Here the service 'myService' is injected in the controller 'myController'. Now we can execute any methods that we define in our service 'myService'.

Built-in Service
AngularJS provides many built-in services that can be used in our application. For example, $http is a built-in service. AngularJS built-in services start with a $ sign. The other useful services are $route, $window, $location etc.

The built-in services can be used by declaring them as dependencies i.e. injecting them as parameters (like the same way used for custom services): 
 var myModule = angular.module('myModule', []);  
 myModule.controller('myController', function($scope, $http) {  
   //...  
   $http.get(...);       
 });  
Here the $http service is injected in the controller 'myController'

Complete example
Here is the complete example:
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">  
           <br>  
           List of books:  
           <br>                  
           <ul>  
                <li ng-repeat="book in bookList">  
                     {{book.name}} -- {{book.author | uppercase}}   
                </li>  
           </ul>  
           Book name: <input type="text" ng-model="bookName" />  
           Author: <input type="text" ng-model="bookAuthor" /> <br>  
           <button ng-click="add()">Add</button>  
      </div>  
        
      <script>        
           var myModule = angular.module('myModule', []);       
             
           myModule.factory('myService', function () {  
                var bookList = [  
                     {name:'The Tempest',   
                          author:'William Shakespeare'},  
                     {name:'Gitanjali',   
                          author:'Rabindranath Tagore'},  
                     {name:'Harry Potter',   
                          author:'J. K. Rowling'},  
                     {name:'The Da Vinci Code',   
                          author:'Dan Brown'},  
                     {name:'A Brief History of Time',   
                          author:'Stephen Hawking'},  
                     {name:'Tell Me Your Dreams',   
                          author:'Sidney Sheldon'}  
                ];  
                  
                var serviceInstance = {};  
                  
                serviceInstance.getBooks = function () {  
                     return bookList;  
                };  
                  
                serviceInstance.addBook =   
                     function (bookName, bookAuthor) {  
                          bookList.push({   
                               name: bookName,   
                               author: bookAuthor   
                          });  
                     };  
                  
                return serviceInstance;                 
           });            
             
             
           myModule.controller('BooksController',   
                function BooksController($scope, myService) {  
             
                     $scope.bookList = myService.getBooks();  
                  
                     $scope.add = function() {  
                          myService.addBook(  
                               $scope.bookName,   
                               $scope.bookAuthor  
                          );  
                     };  
           });                      
       </script>  
 </body>  
 </html>  
The output will be same as our previous post:



[TOC]    << Previous    Next >>

Sunday, May 18, 2014

AngularJS for Beginners: Module

Module can be considered as a container for different components like controllers, services, filters, directives etc. In all our previous examples, we used global namespace for declaring components such as controllers. This is not a good idea to use global namespace since it can cause collisions which are difficult to debug. Instead, we should use module to keep the global namespace clean. The benefit of using module is it makes unit testing easier by testing relevant modules only. 

An application can have several modules. Each module should contain code that implements a specific functionality. The modules of an application can be loaded in any order.  

The recommended way of creating multiple modules for an application:
  • A module for each feature.
  • A module for each reusable component (especially directives and filters).
  • An application level module which depends on the above modules and contains any initialization code.

Declaring a Module
We can declare a module using the angular.module() API method. We have to pass two parameters to the method. The first one is the name of the module. The second one is the list of dependencies. Here is the method signature: 
angular.module('name', [dependencies]);

This is the application of dependency injection. One module may rely on other modules or components to get data. For example, we can create a module without any dependency like the following:
var myModule = angular.module(' myModule ', []);

If the module 'myModule' relies on another module 'requiredModule', the declaration will become:

var myModule = angular.module('myModule', ['requiredModule']);

Creating a Controller in a Module
Here is how we can create a controller in a module:
 var myModule = angular.module('myModule', []);       
 myModule.controller('BooksController', function BooksController($scope)   
 {  
      // controller tasks will be defined below 
           
 });  
Here is the complete example:
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">  
           <br>  
           List of books:  
           <br>                  
           <ul>  
                <li ng-repeat="book in bookList">  
                     {{book.name}} -- {{book.author | uppercase}}   
                </li>  
           </ul>  
           Book name: <input type="text" ng-model="bookName" />  
           Author: <input type="text" ng-model="bookAuthor" /> <br>  
           <button ng-click="add()">Add</button>  
      </div>  

      <script>        
           var myModule = angular.module('myModule', []);
       
           myModule.controller('BooksController',   
           function BooksController($scope) {  
                $scope.bookList = [  
                     {name:'The Tempest',   
                          author:'William Shakespeare'},  
                     {name:'Gitanjali',   
                          author:'Rabindranath Tagore'},  
                     {name:'Harry Potter',   
                          author:'J. K. Rowling'},  
                     {name:'The Da Vinci Code',   
                          author:'Dan Brown'},  
                     {name:'A Brief History of Time',   
                          author:'Stephen Hawking'},  
                     {name:'Tell Me Your Dreams',   
                          author:'Sidney Sheldon'}  
                ];  

                $scope.add = function() {  
                     $scope.bookList.push({   
                          name: $scope.bookName,   
                          author: $scope.bookAuthor   
                     });  
                };  
           });
                      
       </script>  
 </body>  
 </html>   
The output will be same as our previous post:


[TOC]    << Previous    Next >>