Data binding in AngularJS 1 and AngularJS 2

What is data binding?

Data binding which is nothing but  “synchronisation of data between our model (our application) and the view (HTML Template)”. In brief, whenever we change the value in the input box (view), it will be updated to the corresponding scope variable in the model (our application) and vice-versa. [i.e., whenever we change the value of the scope variable in the model, it will be updated to the corresponding input box(view-HTML template)]

Let me explain it with an example:

Figure 1

Figure 2

Relate with a real world example

That’s what data binding is all about. From the above example, can you think of any real world example where data binding plays a major role?

Let me explain further with an example. Most of us have used an IMO mobile app. IMO is nothing but the mobile application which is used for communication. It’s quite similar to whatsapp. You can share images, make voice and video calls, etc. And, yes it is a perfect example of data blinding. If you haven’t understood the concept of what an IMO is, you could try getting a hands-on experience by using the app, that’s definitely help you get a better understanding of IMO.

In IMO, you can see a message which your friend is typing before he/she sends it to you. Please refer the screenshot below.

Real time example for Data binding

Figure 3

Here you can see that the sender is typing the message “How are”(note the cursor, he is typing). Even before he/she hits the “send” button, the receiver would be able to see the message being typed and “How are..” will be displayed in his mobile. This aspect is similar to data binding. What happens exactly is that, while the sender is typing, “How are” is stored in a $scope variable called “message” and {{message}} is used to display the message “How are” to the receiver.

Looking at it from a technical point-of-view, whenever we make changes in the view (here the view is nothing but the box in which the sender is typing), the same will be updated in the scope variable message of the model (here model is nothing but our application) and vice versa. This might not be exactly how an IMO works. I’ve used this example just to explain the concept of data binding better.

Data Binding in AngularJS

All angular developers know that data binding is one of the best features in the Angular framework. It is available in both versions Angular 1 and Angular 2. However, they might be a bit different from each other, since a few updates have been made in Angular 2  to increase the performance. We will see how data binding works in Angular 1 and Angular 2. Before that, you need to understand about digest cycle in AngularJS 1. Once you understand the digest cycle, I can easily walk you through data binding concept in angular 1.

$digest cycle

$digest cycle is nothing but a loop. Inside that, we have $watch list. The $watch is used to detect the change in scope variable. If it finds any changes, then it updates the scope variable with a new value.

Let’s take our previous example into consideration; I have used a scope variable called “message”. Each scope variables will have different watchers. The watchers will be added to watch list. Now we have only one watcher because I used only one variable. The syntax for $watch is mentioned below,

Figure 4

Watcher’s are fired from the $digest cycle. Now, this raises the question of when the $digest cycle starts and who starts it? Whenever the events are fired (here we are firing the ‘oninput’ event whenever we typing the input) $apply service internally starts the digest cycle which would then initiate the watcher. The watcher then finds the changes and update the new value in the scope variable.

$digest cycle resolves the watcher list through the process called “Dirty Checking”. You can find more about dirty checking below.

Dirty Checking

Dirty checking is nothing but a process which walks through the $watch list. It compares the newValue with oldValue of the each watcher in the $watch list. If a value changes, it makes a record of it and continues to the next watcher. Once it finishes one cycle, it continues to the next cycle until it makes sure that nothing has been modified in the $watch list.

Data Binding in AngularJS 1

In AngularJS 1, there are three types of data binding.

  1. One-way data binding
  2. Two-way data binding
  3. Event binding

One-way data binding

In Figure-1, I’ve  mentioned about “binding a scope variable’s value to an HTML element (which is nothing but our view),” this is how one-way data binding works. Here the binding is only one-way, not two-way (which is binding scope variable value to the input field and updating the variable value whenever we make changes there).

I have used ng-bind directive and interpolation to achieve one-way data binding. Let me show you how this works,

ng-bind

View

<h1 ng-bind=”message”></h1>

model

var dataBindingApp=angular.module(“dataBinding”,[]);

dataBindingApp.controller(“dataBindingController”,function($scope){

$scope.message=”Hello Angular Developers”;

});

Result

Hello Angular Developers

Here, ng-bind is a directive, and it will place a watcher on the scope variable assigned to it. With the help of this watcher, it will bind the value to the HTML element.

Interpolation

View

{{message}}

model                                                                                                                  

var dataBindingApp=angular.module(“dataBinding”,[]);

dataBindingApp.controller(“dataBindingController”,function($scope){

$scope.message=”Hello Angular Developers”;

});

Result

Hello Angular Developers

Whereas, in this case, the binding is done using the {{}} braces. Both ng-bind and interpolation are used to achieve one-way data binding. But there are some differences between these two methods.

Difference between ng-bind and interpolation

In most cases, ng-bind is better than interpolation. Because ng-bind will only apply when the passed value actually changes. The brackets, on the other hand, will be dirty checked and refreshed in every $digest, even if it’s not necessary.

I’d say ng-bind is better than interpolation. Why? Because, let’s consider the page is loading, in the intermediate time, the template “{{message}}” itself would be displayed for a short span of time if we use interpolation. This issue arises as the template is loaded before Angular JS compiles its elements. But, when we use ng-bind this would not happen, as ng-bind is an element attribute, it would make the binding invisible when the page is being loaded. Using the “ng-cloak” directive along with interpolation like I’ve listed below, could help us avoid flashing of the data when the page is loading.

<p ng-cloak>{{message}}</p>

Two-way data binding

Let me explain the concept of two-way data binding using Figure 1. There, I used ng-model directive and assigned a scope variable ‘message’ to that to achieve two-way data binding. On giving input to the text box, digest cycle is called, and it fires the watchers. The watchers then update the newValue to the scope variable “message”, and I’ve bound them to the HTML element through the interpolation “{{message}}”.

Event binding

Events are actions which occur as a result of the user or another source. Let us look at a few examples:

  1. When you click a button, it is a “click” event.
  2. when you double click something, it is a “double click” event.
  3. When you press any key on your keyboard, it is a “keypress” event.

Normally we can bind events to HTML elements using javascript, jquery, etc. Let me explain the differences below:

Javascript

View:

<h1 id=”javascript”>Event Binding in pure javascript</h1>

model:

document.getElementById(“javascript”)

.addEventListener(“click”,function(){

console.log(Event Binding in javascript);

});

Jquery

View:

<h1 id=”jquery”>Event Binding in jquery</h1>

model:

$(“#jquery”).bind(“click”,function(){)

console.log(Event Binding in jquery);

});

AngularJS

View:

<h1 ng-click=”onClick()”>Event Binding in AngularJS</h>

model:

$scope.onClick=function(){

console.log(Event Binding in AngularJs);

});

In both javascript and jquery, we have to bind the event and the corresponding handler functions manually using their id’s. But, AngularJS framework provides many built-in directives for event binding in AngularJS such as ng-click, ng-keypress, ng-mouseover, etc. Here, the ng-click directive is used to bind the click event to the HTML element, and we just have to define the corresponding handler functions($scope.onClick) in the model.

Data binding in AngularJS 2

Angular 2 has the following types of data binding.

  1. One-way data binding
  2. Event binding
  3. Two-way data binding

Before we look at the type of data bindings, let us find out how data binding works in Angular 2.

How data binding works in Angular 2

  In Angular 1 $watchers in the $digest cycle are used to perform data binding. But in Angular 2, the $watch is replaced with a new concept called “change detection.

Change detection

As the name suggests, the main goal of the change detection is to find the changes. Ideally, when would a change occur? Can you make a guess?

Changes occur whenever we perform some events like click, submit, etc., or whenever we fetch data from remote.

How will Angular recognise the changes? Would any elements notify it? Here comes the concept called “Zone”. There is a directive called NgZone in Angular 2 and it is used for data binding internally. Let’s have a look at it:

  1. Whenever we perform some events the ngZone OnTurnDone event in ApplicationRef (It’s a predefined class in Angular2) class is fired.
    Class  ApplicationRef{
    changeDetectorRefs: changeDetectorRef []=[];
    constructor(private zone:NgZone){
    this.zone.OnTurnDone.subscribe(()  =>  this.zone.run()  =>  this.tick());}}
  2. Whenever OnTurnDone event is fired, it executes tick() function. This function is used to perform change detection for all the component in the application.
    Tick(){
    this.changeDetectorRef.forEach((ref) => ref.detectChanges() );
    }

    here  changeDetectorRefs is an array of change detector for each component.

After running the change detector function of each component, the DOM gets updated. This is how change detection works in angular 2. Each component has it’s own change detector. Change detection is always performed from root component to sub-component.

One-way data binding

    I prefer using property binding instead of ng-bind and interpolation which were used in angular 1 to achieve one-way data binding. You may wonder why I prefer property binding here? Because, in Angular 1,  there are lots of built-in directives. I just want to remove some directives and use other existing concepts. Let me explain in detail:

Property binding

               Instead of using directives I could also use the properties (which already exist) of the HTML elements inside a square bracket to achieve one-way data binding. Please find the example below,

Figure 5

value – property or attribute of the HTML element.

VariableInComponent – variable in the MainComponent.

Here I am binding the value of VariableInComponent to the property or attribute of the HTML element. You can also use a custom HTML tag and their corresponding property (you can bind the MainComponent property value to the SubComponent property).

Interpolation

There is no difference in interpolation with angular 1 and Angular 2.

Event binding

    In angular 1, we used the ng-click directive to bind the click event. But here we are going to use the normal click event wrapped in brackets to represent an event. I’ve mentioned already that, in property binding, there are several random event binding directives like ng-click,ng-blur,ng-double click, etc. In angular 2, all these event binding directives have been removed. Take a look at the example listed below,

template:

<h1 (click)=”onClick()”>Event Binding in angular2</h1>

Two-way data binding

Angular 2 does not have any built-in Two-Way data binding. It does not mean; we cannot have two-way data binding in Angular 2 application. However, it could be achieved using ngModel directive, combining the concepts of event and property binding. The surprising thing is that two-way data binding could also be achieved in Angular 2 even without ng-model directive. Because, as I mentioned earlier with a combination of property and event binding two-way binding could be implemented. In Angular 1, we’ve used the ng-model directive to achieve two-way data binding. But here we can do it without using ng-model. Let’s see how to go about it,

Two way data binding

Figure 6

From the above example, you could see how we could go about implementing two-way data binding without the use of ng-model. Yes, we did it just by combining property and event binding. Despite the fact that Angular 2 doesn’t have any built-in two-way data binding, we have managed to achieve it by property binding and event binding. Now, let’s see how two-way data binding could be accomplished using ng-model directive below,

<input type=”text” [(ngModel)]=  “variableInComponent” >
{{variableInComponent}}

Actually, the ngModel directive in angular 2 is a combination of event binding and property binding. The internal working of  two-way data binding using ngModel directive in Angular 2 would look like,

<input type=”text” [ngModel]=  “variableInComponent” (ngModelChange)=”variableInComponent=$event”>

{{variableInComponent}}

ngModel – input property

ngModelChange – instance of EventEmitter class

Here [ngModel] is a property binding which binds property value to an HTML element and (ngModelChange) is an event binding which notifies the changes whenever an event happens. Instead of writing ngModel and variableInComponent twice (see the above code) angular uses a shorthand syntax [()].

Is Angular 2 a better option for data binding instead of Angular 1?

  • Do you recall how $digest cycle works? In Angular 1, $apply service starts digest cycle internally. To be honest, we need to start the digest cycle manually by wrapping a code inside the $apply function (angular will internally do it) in most cases. But in some cases, Angular may not know about some functions like setTimeout(). In those cases, we would have to manually start the digest cycle by wrapping a code inside a $apply function to detect the scope variable changes,
setTimeout(function(){

$scope.$apply(function(){

$scope.variableOnScope=”setTimeout Function is called”;})

},1000);

But in Angular 2, we don’t have to do this. Zone takes care of all the asynchronous calls.

  • Change detection is performed in a directed way (from root to sub-component) thus improving the performance considerably. While $digest loop is not a directed one. It just watches the scope variable randomly.
  • We cannot stop the $digest cycle, and so, the digest cycle may run an infinite number of times. If the scope variables increase, the watcher’s size will also increase. If the size of the watcher’s increases, the loop will run numerous times in the background. As a result, the response time of the application would increase as well. This aspect would affect the performance of the application.
  • Change detection walks through the whole tree. However, if you want to stop change detection for a particular component and the subcomponents of that specific component, and in case, the properties of the component don’t change, we can do that using Immutable objects and observables.

1 Comment

Comments are closed.

how can we help you?

Tell us about your requirement and we’ll offer you the best possible solution. Get in touch now.