Friday, July 26, 2013

Compile vs link And Bootstrap process in AngularJS

To understand the difference between compile and link, we need to understand how Angular bootstrap the app, that is why i combined these 2 topics.
To bootstrap any angular app, it is just writing a "ng-app" tag in the HTML and that is all, but behind the scene what happens, we don't know. I tried to explore it in detail and that is what i came up with.
Before we go into the detail, please read startup section from Angular site (http://docs.angularjs.org/guide/concepts) -

Here is my understanding how it works -

Lets try to bootstrap the application manually, instead of relying upon Angular. For this we will have to wait for application's DOM to get ready. I have bootstrap code in the window.onload and here is the code with the detail comments -

Here is the HTML code -
 <body ng-controller="Demo">
      Name: <input ng-model="name" />
      <div>
          Hello <span ng-bind="name"></span>
      </div>
      <ul>
          <li ng-repeat="i in [1,2,3]">{{i}}</li>
      </ul>
  </body>

Here is the JavaScript -
var myApp = angular.module('myApp', []);
function Demo($scope) {}

window.onload = function () {
var $rootElement = angular.element(window.document);
var modules = [
'ng',            
'myApp',
function($provide){
$provide.value('$rootElement', $rootElement);
}
];

var $injector = angular.injector(modules);
var $compile = $injector.get('$compile');
var compositeLinkFn = $compile($rootElement);
var $rootScope = $injector.get('$rootScope');
compositeLinkFn($rootScope);
$rootScope.$apply();
}

Explaination of Code -
var $rootElement = angular.element(window.document);
wait for DOM to load;
get the root of the document,normally location of ngapp, in our case just the root element

var modules = [..];
get list of modules

Inside module the 1st module we mentioned is - 'ng' which os inbuilt module of Angular. for manual bootstrap we need to mention it. If we won't mention it we will get this error -Unknown provider: $compileProvider <- compile="" p="">
Next i mentioned myApp, which is the module i wanted to bootstrap
'myApp'

After this there is 3rd inline module, just for demonstration purpose.
function($provide){
$provide.value('$rootElement', $rootElement);
}

var $injector = angular.injector(modules);
Get the rootinjector of the application. There can only be one injector instance per application and not per module.
Above line creates the injector and returns its object.

var $compile = $injector.get('$compile')
It returns the compile service, which actually compile the code. If you read the article on Angular Overview from Angular official site, then it is the same compile service it was talking about.
compile service traverse the DOM and get the directives and returns the link fn collection.

var compositeLinkFn = $compile($rootElement);
We get the linking function using compile service.

var $rootScope = $injector.get('$rootScope');
get the rootscope. It is the same root element where we write the ng-app tag to make it an Angular app.

compositeLinkFn($rootScope);
Call the link function, that is where actual mapping of view with the original object happens.

$rootScope.$apply();
command Angular to render the view for you.

The above code demonstrate how Angular bootstrap the app, But it doesn't give any details on compile Vs link, Which is the topic of this article. Well Lets talk about it now.
Compile - It works on template. Its like adding a class element in to the DOM.
Link - It works on instances.
The concept of compile and link comes from C, where we first compile the code and then link it to actually execute it. The process is very much same in Angular as well.
In Angular not every directive will be able to demonstrate it, but "repeate" directive shows the difference very clearly.
To understand the difference lets try to debug the above code. Attach the debugger at line 2, 16 and 20. Here is the screent shot what i see when i am at line 2 -




The code looks very much similar to the one i have written in my HTML, no difference yet.Lets see what happens at line 16 - 



We actually compiled the repeat tag and repeater compile function knows it has to create bunch of copies, hence it keeps the original syntax in comment and then internally compile the template itself.
Lets move to line 20 - 

linking function creates the view.Once linking function is executes it creates the view, but it wont change the DOM itself, Once we call apply() function of angular, it renders the view for you.

Monday, July 22, 2013

AngularJS scope Inheritance-1

JavaScript prototypical inheritance -

Before talking about AngularJS scope inheritance lets have a quick recap on what is prototypical inheritance in javascript is.
We all know its possible to have parent child relationship in javascript(If you don't know, please go through the old articles under javascript section to get more insight). When we try to refer to any property in child object and if its available with child then we get the value immediately, but if we the property is not with child, then javascript try to get the value from its parent.
Let's try to understand it by example - 
say there is parent and child object. The prototype of child is parent. 
parent.p1 = 'p1';
child.c1='c1';

alert(child.c1) --> c1, directly from child object
alert(child.p1) -->p1 , from its parent

now we write child.p1 = 'cp1';
alert(child.p1); --> it will alert cp1. In other words defining the same property on child hides the parent's property.

Scope Inheritance in Angular - 
Scope inheritance is very much straight forward in angular, until we have 2 way binding to primitive types defined in parent from child. If we have such binding and child gets its own property which hides the parent property, then it causes unexpected output. This is not Angular specific, but the behavior of javascript only.

We will try to understand the scope inheritance in case of different directives defined in Angular. 
(For the detail of the functionality provided by different directives, please refer - http://softtechhelp.blogspot.in/2013/07/angular-js-inbuilt-directives.html )

ng-include
It creates a new child scope and inherits from parent. 
lets say we have following properties available in our controller scope(of index.htm) -
$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

In our view we have following code -
tmpl1.htm -
<input ng-model="myPrimitive">

tmpl2 -
 <input ng-model="myObject.aNumber">

index.htm -
<div ng-include src="'/tmpl1.htm'"></div>
<div ng-include src="'/tmpl2.htm'"></div>

In our index.htm i have included both template htm using ng-include tag. If you see carefully we have 2 way binding with a primitive in tmpl1 and binding with reference type in tmpl2.
As per definition both child should create it's own scope and should inherit from parent scope. Which means both myPrimitive and myObject will be available to tmpl1 and tmpl2.

In tmpl1 i have tried to access myPrimitive and as its not been defined in current scope, hence it will be availed from its parent. In the similar way, myObject in tmpl2 will also be referred from parent scope only.

What will be the value of myPrmitive  and myObject.aNumber will be, if we type "123" and "456" in input box of tmpl1 and tmpl2?
The first impression comes is, it will be "123" and "456". But if you think about scoping, then typing any value in text box in tmpl1 will introduce a new property "myPrimitive" in child scope and parent property will remain intact. in case of myObject, in tmpl2 we are referring to myObject.aNumber. as myObject is not available in child scope, hence it will be referred from parent only and it will modify original parent's myObject.

What if we really want to modify the value of myPrmitive of parent from child input? The simplest way would be to use $parent.
So the code in tmpl1.htm would be -
<input ng-model="$parent.myPrimitive">

Here is the HTML which can demonstrate you the full example -
  <body>
    <div ng-controller="Ctrl">base page-<br />
        input 1 - <input ng-model="myPrimitive" /><br />
        input 2 - <input ng-model="myObject.aNumber" />
        <br />
        <div ng-include src="'tmpl1.html'"></div>
        <div ng-include src="'tmpl2.html'"></div>    
    </div>
  </body>

function Ctrl($scope) {
    $scope.myPrimitive = 50;
    $scope.myObject = { aNumber: 11 };
}
NOTE - in ng-include, if you are writing any html, then put single quote inside double quote to mention the html file path.

ng-repeat -
scoping in ng-repeat is slightly different. ng-repeat work on collection. So lets take an example of an array of primitives and array of javascript objects.
$scope.primitives= [ 123, 456 ];
$scope.objects = [{num: 111}, {num: 222}]
<ul><li ng-repeat="num in primitives">
       <input ng-model="num">
    </li>
<ul>
<ul><li ng-repeat="obj in objects ">
       <input ng-model="obj.num">
    </li>
<ul>

ng-repeat creates a new child scope for each iteration. And in case of primitive values, a copy of primitive is assigned to the child scope. Hence modifying the value in text box wont change anything in parent. The case will be different for objects, where original parent's  object will be modified.

Here is the HTML which can demonstrate you the full example -
    <div ng-controller="Ctrl">base page values-<br />
        primitive array items = {{primitives | json}}<br />
        object array items = {{objects | json}}
        <br />
     
        ng-repeat demo - <br />
         <ul>
            <li ng-repeat="obj in objects">
                <input ng-model="obj.num" />
            </li>
        </ul>
        <div>
             <div ng-repeat="item in primitives">
                <input ng-model="item" />
            </div>
        </div>
     
    </div>

function Ctrl($scope) {
    $scope.primitives = [123, 456];
    $scope.objects = [{ num: 111 }, { num: 222 }];
}

NOTE - If you try to type anything in the input binded with primitive, you will see you are not able to edit it. This is because, once you edit it, Angular's binding update it with the parent's value(which is still old). this is because editing child's field wont update the parent, and you will always see the old value.
For more detail on this problem, please read - 

ng-controller -
The scope inheritance will be very much same we discussed in ng-include.

ref - https://github.com/angular/angular.js/wiki/Understanding-Scopes#wiki-ngInclude

Sunday, July 14, 2013

AngularJS inbuilt directives

This post will give introduction about different tags(directives) available in Angular.

In this post we will be focusing on -
ng-include
ng-repeat
ng-controller
ng-view

ng-include-
Using ng-include tag we can fetch any external HTML file in our current HTML. Just like script tag where we can include external javascript file, in the similar way using ng-include we can include external html file as well. This HTML will be embedded into our original html itself.
Ex. - <div ng-include src="'view/menu.htm'" ></div>

ng-repeat-
This is equivalent to traditional foreach loop. Using this directive you can write a foreach loop in HTML as well. Generally we write ng-repeat on a collection. We take the each values of collection and repeate the underlying tag.
Ex . -
<ul ng-repeat="items in itemArray">
<li>
   <div>{{item.name}}<div>
</li>
</ul>

itemArray should be defined in the controller scope. The above code traverses on itemArray and repeat the "ul" tag with every value and populate the name property of item in the mentioned Div element.

ng-controller -
ng-controller is a directive by which angular supports the idea of code behind for MVC implementation.(There are alternative ways possible to define controller, but this is the simplest and popular way to define controller).
Here is the example from Angular official site -
The above diagram gives very simple view of how controller, view and scope are related. controller is defined in view with ng-controller directive and the corresponding scope is available in the function "MyCtrl".  Once Angular checks this directive in the HTML it looks for corresponding definition in the JavaScript and injector take cares of mapping the scope, view and controller.

ng-view-
This tag is very usefule once we write single page application using routing framework provided by Angular. We wont go into the detail of routing framework, but its more of the mechanism in which once you change the url, the corresponding view (defined in configuration) gets loaded automatically. This view render happens inside this ng-view tag only. It is very much similar to MVC ASP .NET app, where you hit the controller and the corresponding view get renders.
Ex. - available here - http://docs.angularjs.org/api/ng.directive:ngView

AngularJS Basic terms

Today we will try to understand the basic terms used in Angular. 

Injector -
Injector is responsible for assembling the application. We might have multiple services, controllers etc, which might be interdependent. injector take cares of initializing the prerequisite of any of the services, controllers.

Module -
Module is something which configures the injector. It tells the injector what all we have in our scope. anything defined in given module will be visible to injector. Once we create service or controller or anyother component in a single module, all will be linked together via injector. You can visualize module to be a container where all your components like service/controller etc will be defined and injector will manage them. components inside one module will directly wont be visible outside the module.

Scope - The scope in Angular is very much same as JavaScript scope. Scope defines the boundry of your code. Example  - in view we define the controller. The scope of that controller is very much limited to that view only.
<Div ng-controller='myCtrl' > </Div>
myCtrl is the controller which is nothing but a javascript function. Anything you define in this function will be available to this Div element. Hence we can say the scope for this controller is the mentined Div element.
this concept can be visualized with following diagram(taken from Angular official docs) -

rootScope -
rootScope is parent of all scopes. It is the scope of your module. you can access any scope from rootscope.

Directive -
Directives are custome html, which lets you teach html new tricks. for example say there is no tag in HTML named as "list". You can create a tag named as list using directive and write code to give list like behavior to this tag.

Other key words(Won't go into the details) -
Model - Application Data
View - What user sees
Controller - application behavior
$- angular namespace

Saturday, July 13, 2013

AngularJS overview

This is very high level introduction to what Angular is, and how it is different from any other javascript framework.

If you go to the home page of Angular the very first line explains it -
"AngularJS is a structural framework for dynamic web apps"
but what does it mean? Well the first impression comes to our mind when we think about Angular JS as a javascript library is, we already have many libraries (JQuery) available in javascript, which are very mature and very well adapted by the market, then why do we need a new one. Is there any advantage of Angular over JQuery? Well the answer would be NO.
Its not because Angular is not powerful, it is because JQuery and Angular serves different purpose. To achieve fully functional we app in Javascript, you might need to use Angular and JQuery together.

The question remain same, why Angular?
There is very good paragraph on Angular official web site -

The impedance mismatch between dynamic applications and static documents is often solved with:
  • a library - a collection of functions which are useful when writing web apps. Your code is in charge and it calls into the library when it sees fit. E.g., jQuery.
  • frameworks - a particular implementation of a web application, where your code fills in the details. The framework is in charge and it calls into your code when it needs something app specific. E.g., knockoutember, etc.
Angular takes another approach. It attempts to minimize the impedance mismatch between document centric HTML and what an application needs by creating new HTML constructs. Angular teaches the browser new syntax through a construct we call directives
Angular provides you an inbuilt MVC pattern for your client side application. you can have view,model and Controller in your javascript(Which is ofcourse not provided by core javascript).

Controller code you write in javascript(Or JQuery) and update the model. Angular framework takes the responsibility of updating the view for you.

Angular provide you a way by which you can make static HTML to be dynamic(using {{}} tag).
It allows you to attach code behind with the DOM element.

you can create your own customized tags,attributes for your application and provide them different behavior.

It allows you to write HTML component which can be reusable in different applications.