Learn Angular 4.0 In 10 Days - Data Binding - Day Three

Let us start the Day 3 of Learning Angular 4.0 in 10 Days. In the previous articles, we already discussed Angular Framework and Components. If you want to read the previous articles of this series, do visit the below link.
Now, in this article, we will discuss the Data Binding concept in Angular. Data Binding is one of the most important and fantastic features of Angular 4.0.

What is Data Binding?

Data-binding in Angular apps is the automatic synchronization of data between the Model and the View components. The way that Angular implements data-binding lets you treat the Model as the single-source-of-truth in your application. The View is a projection of the Model at all times. Data binding is the process that establishes a connection between the application UI and business logic. If the binding has correct settings and the data provides proper notifications, then whenever the data changes its value, the elements that are bound to the data reflect changes automatically.

Why Data Binding is required

In traditional web development, we need to develop a bridge between front-end, where the user performs their application data manipulation, and the back-end, where the data is stored. Now, in this development, the process is driven by consecutive networking calls and communicating changes between the server (i.e. back-end) and the client (i.e. front end). For the solution of this problem, Angular involved this data binding concept.

Most web framework platforms focus on one-way data binding. Basically, this involves reading the input from DOM, serializing the data, sending it to the back-end or server, waiting for the process to finish. After it, the process modifies the DOM to indicate errors occurred (if any) or reloads the DOM element if the call is successful. While this process provides a traditional web application all the time, it needs to perform data processing. This benefit is only really applicable to web apps with highly complex data structures. If your application has a simpler data structure format with relatively flat models, then the extra work can needlessly complicate the process and decrease the performance of your application. Furthermore, all models need to wait for server confirmation before their data can be updated, meaning that the related data, depending upon those models, won’t have the latest information.

The Angular framework addresses this with data binding concept. With data binding, the user interface changes are immediately reflected in the underlying data model, and vice-versa. This allows the data model to serve as an atomic unit that the view of the application can always depend upon to be accurate. Many web frameworks implement this type of data binding with a complex series of event listeners and event handlers – an approach that can quickly become fragile. Angular, on the other hand, makes this approach to data a primary part of its architecture. Instead of creating a series of callbacks to handle the changing data, Angular does this automatically without any needed intervention by the programmer. Basically, this feature is a great relief for the programmer.

So, the primary benefit of data binding is that updates to (and retrievals from) the underlying data store happen more or less automatically. When the data store updates, the UI updates as well. This allows us to remove a lot of logic from the front-end display code, particularly when making effective use of Angular’s declarative approach to UI presentation. In essence, it allows for true data encapsulation on the front-end, reducing the need to do complex and destructive manipulation of the DOM.

While this solves a lot of problems with a website’s presentation architecture, there are some disadvantages to take into consideration. First, Angular uses a dirty-checking approach that can be slow in some browsers – not a problem for small presentation pages, but any page with heavy processing may run into problems in older browsers. Additionally, data binding is only truly beneficial for relatively simple objects. Any data that requires heavy parsing work, or extensive manipulation and processing, will simply not work well with two-way binding. Additionally, some uses of Angular – such as using the same binding directive more than once – can break the data binding process.

What is Dirty Checking?

In Angular, Model and View are interconnected with the binding mechanism. So that any changes made in the view will update the model and vice versa. This update of model or view occurred due to the model change event which is called Digest Cycle and dirty check is one of the parts of Digest Cycle. Actually, when any event or model value manipulation is done, angular itself check the old value and new value and if the value does not match, then the digest cycle starts its work and update the view by checking the model value and find which object needs to be changed. Actually, the digest cycle informs the watchers about the model change and then watchers synchronize the view with the model data. Now while this updation process is going on, it is possible that the value of model again changed. So now, the dirty check comes into the picture and checks while the digest cycle(was going on) anything is changed in the model or not . If any thing changed, it will call the digest cycle again and update the view accordingly, and this process will go on until dirty check finds no updates done while last Digest cycle.

Angular always creates a change detector object per component, which tracks the last value of each template binding, such as {{employee.name}}. In normal scenerio, after every asynchronous browser event execution (such as a response from a server, or a click event, or a timeout event), Angular change detection executes and dirty checks every binding using those change detector objects. 

If a change is detected, the change is propagated. E.g.,
  • If an input property value changed, the new value is propagated to the component's input property.
  • If a {{}} binding value changed, the new value is propagated to DOM property textContent.
  • If the value of x changes in a style, attribute, or class binding – i.e., [style.x] or [attr.x]or [class.x] – the new value is propagated to the DOM to update the style, HTML attribute, or class.

Angular uses Zone.js to create its own zone (NgZone), which monkey-patches all asynchronous events (browser DOM events, timeouts, AJAX/XHR). This is how change detection is able to automatically run after each asynchronous event. I.e., after each asynchronous event handler (function) finishes, Angular change detection will execute.

Different Types of Data Binding

In Angular 4, there are different types of data binding mechanism is available. There are,

  1. Interpolation
  2. Property Binding
  3. Two Way Binding
  4. Event Binding
Interpolation

Interpolation data binding is the most popular and easiest way of data binding in Angular 4. This mechanism is also available in the earlier version of the angular framework. Actually context between the braces is the template expression that Angular first evaluates and then convert into strings. Interpolation use the braces expression i.e. {{ }} for render the bound value to the component template. It can be a static string or numeric value or an object of your data model. As per example, in angular we use it like below
  1. {{model.firstName}}
 Here model is the instance of the controller objects. But in angular 4, it is now much simpler where controller instance name removed from the expression i.e.
  1. {{firstName}}
Property Binding

In Angular 4.0, a new binding mechanism introduces which called property binding. But actually in nature is just same as interpolation. Some people also called this process as one way binding as like previous angularjs concept. Property binding used [] to send the data from the component to the html template. The most common way to use property binding is that assign any property of the html element tag into the [] with the component property value, i.e.

  1. <input type=”text” [value]=”data.name”/>

In the previous version of angularjs, it can be done by using ng-bind directives. Basically property binding can be used to bind any property, component or a directive property. It can be used as

  1. Attribute binding
  2. Class binding
  3. Style binding
Sample Code of app.component.interpolation.ts 
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'interpolation',  
  6.     templateUrl: 'app.component.interpolation.html'  
  7. })  
  8.   
  9. export class InterpolationComponent {  
  10.     value1: number = 10;  
  11.     array1: Array<number> = [10, 22, 14];  
  12.     dt1: Date = new Date();  
  13.   
  14.     status: boolean = true;  
  15.   
  16.     returnString() {  
  17.         return "String return from function";  
  18.     }  
  19. }  
Sample code of app.component.interpolation.html  
  1. <div>  
  2.     <span>Current Number is {{value1}}</span>  
  3.     <input [value]="value1" />  
  4.     <br /><br />     
  5.     <br /><br />  
  6.     <span>Current Number is {{value1 | currency}}</span>  
  7.     <br /><br />  
  8.     <span>Current Number is {{dt1}}</span>  
  9.     <br /><br />  
  10.     <span>Current Number is {{dt1 | date}}</span>  
  11.     <br /><br />  
  12.     <span>Status is {{status}}</span>  
  13.     <br /><br />  
  14.     <span>{{status ? "This is correct status" :"This is false status"}}</span>  
  15.     <br /><br />  
  16.     <span>{{returnString()}}</span>  
  17. </div>  
Output

 

Two Way Binding

The most popular and widely used data binding mechanism in two-way binding in the angular framework. Basically two-way binding mainly used in the input type field or any form element where user type or provide any value or change any control value in the one side, and on the other side, the same automatically updated in to the controller variables and vice versa. In the Angular 1.x, we use ng-model directives with the element for this purpose.

  1. <input type=”text” ng-model =”firstName”/>   

 

Similarly, in Angular 4.0, we have a directive called ngModel and it need to be used as below –
  1. <input type=”text” [(ngModel)] =”firstName”/>  

As we see, in Angular 4, the syntax is different because we use [] since it is actually a property binding and parentheses is used for the event binding concept. I will discuss about ngModel directives in the later section of this article.

Sample code of app.component.twowaybind.ts
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'twowaybind',  
  6.     templateUrl: 'app.component.twowaybind.html'  
  7. })  
  8.   
  9. export class TwoWayBindComponent {  
  10.     val: string = "";  
  11. }  
Sample code of app.component.twowaybind.html
  1. <div>  
  2.     <div>  
  3.         <span>Enter Your Name </span>  
  4.         <input [(ngModel)]="val" type="text" />  
  5.     </div>  
  6.     <div>  
  7.         <span>Your Name :- </span>  
  8.         <span>{{val}}</span>  
  9.   
  10.     </div>  
  11. </div>  
Output 

 
Event Binding

Event Binding is one of the new mechanisms introduced by Angular 4.0. In the previous version of the Angular, we always used different types of directives like ng-click, ng-blur for binding any particular event action of an HTML control. But in Angular 4, we need to use the same property of the HTML element (like click, change etc) and use it within parenthesis. So, in Angular 4, with properties, we use square brackets and in events, we use parenthesis.

  1. <button (click)=”showAlert();”>Click</button>  
What is ngModel

As I already said in the previous section of the article, ngModel basically performs both property binding and event binding. Actually, property binding of the ngModel (i.e. [ngModel]) perform the activity to update the input element with value. Where as (ngModel) (basically in fired the (ngModelChange) event) instruct the outside world when there are any change occurred in the DOM Element.

Sample Code of app.component.eventbinding.ts
  1. import { Component, OnInit } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'event-bind',  
  6.     templateUrl: 'app.component.eventbinding.html'  
  7. })  
  8.   
  9. export class EventBindingComponent implements OnInit {  
  10.     showAlert() {  
  11.         console.log('You clicked on the button...');  
  12.         alert("Click Event Fired...");  
  13.     }  
  14.   
  15.     ngOnInit() {  
  16.   
  17.     }  
  18. }  
Sample code of app.component.eventbinding.html
  1. <div>  
  2.     <input type="button" value="Click" class="btn-block" (click)="showAlert()" />  
  3.     <br /><br />  
  4.     <input type="button" value="Mouse Enter" class="btn-block" (mouseenter)="showAlert()" />  
  5. </div>  
Output

 
 
Component Heirarchy

In practical world, TypeScript supports decorators (sometimes it is referred as annotations) which is basically used to declaratively add or change any existing thing. For example, class decorators can add metadata to the class’s constructor function or even alter how the class behaves. In real world, components are not native JavaScript entities, Angular provides a way to define a component by pairing a constructor function with a html based view. We can do this by defining a constructor function (in TypeScript it is defined as a class) and using a decorator to associate our view with the constructor. The decorator can also set various configuration parameters for the component. This magic is accomplished using the @Component decorator which we already saw in the previous section of this series.

The above scenario describes the basic architecture of an individual component but Angular 4.0 applications are always made up of a hierarchy of components – they actually begin with a root component that contains as descendants all the components used in the application (basically in every angular module, bootstraps component is actually act as a root component). Components are intended to be self-contained because we want to encapsulate our component functions and we don’t want other code to arbitrarily reach into our components to read or change properties. Also, we don’t want our component to affect another component written by someone else. At the same time components do need to exchange data. In Angular 4, a component can receive data from its parent as long as the receiving component has specifically said it is willing to receive data. Similarly, components can send data to their parents by trigger an event the parent listens for. Let’s look at how the component hierarchy behaves. To begin, we can draw it as follows,



Each rectangular box in the above component represent a component and technically this representation is called “graph” – a data structure consisting of nodes and connecting “edges.” The arrows represent the data flow from one component to another and we can see that data flows in only one direction – from the top downwards to descendants. Also, note there are no paths that allow you to travel from one node, through other nodes and back to the one where you started. The official name for this kind of data structure is that a “directed acyclic graph”, i.e. it flows in only one direction and has no circular paths in it.

 

This kind of structure has some important features: it is predictable, it is simple to traverse and it is easy to see what is impacted when a change is made. For Angular’s purposes, when data changes in one node, it is easy to find the downstream nodes that could be affected. A simple example of how this might be used is a table with rows containing customers and information about them in which a table component contains multiple individual row components that represent each customer. The table component could manage a record set containing all the customers and pass the data on an individual customer to each of the row components it contains. This works fine for simply displaying data but in the real world data will need to flow the other way – back up the hierarchy – such as when a user edits a row. In that case the row needs to tell the table component that the data for a row has changed so the change can be sent back to the server. The problem is that as diagrammed above, data only flows down the hierarchy, not back up. To ensure we maintain the simplicity of one-way data flow down the hierarchy, Angular 4 uses a different mechanism for sending data back up the hierarchy: events.

Now, when a child component takes an action that a parent needs to know about, the child fires an event that is caught by the parent. The parent can take any action it needs which might include updating data that will, through the usual one-way downwards data flow, update downstream components. By separating the downward flow of data from the upwards flow of data, things are kept simpler and data management performs well.

@Input() Decorator

In a component-driven application architecture, we typically use stateful and stateless components. The key concept is having some form of “stateful” component that delegates down into a “stateless” child, or children, component(s). Using the same concept above with bindings, which relies on parent data, we need to tell Angular what is coming into our component. @Input is a decorator to mark an input property. It is used to define an input property to achieve component property binding. @Input decorator binds a property within one component (child component) to receive a value from another component (parent component). This is one way communication from parent to child. The component property should be annotated with @Input decorator to act as input property. A component can receive a value from another component using component property binding. Now we will see how to use @Input. It can be annotated at any type of property such as number, string, array or user defined class. To use alias for the binding property name we need to assign an alias name as @Input(alias).
Find the use of @Input with string data type.

  1. @Input() caption : string;    
 Now find array data type with @Input decorator. Here we are aliasing the property name. In the component property binding, alias name arrObjects will be used.
  1. @Input('ctArray') arrObjects : Array<string>  
@Output() Decorator

In Angular 4, @Output is a decorator to mark an output property. @Output is used to define output property to achieve custom event binding. @Output will be used with the instance of EventEmitter. Now find the complete example step by step. @Output decorator binds a property of a component to send data from one component (child component) to calling component (parent component). This is one way communication from child to parent component. @Output binds a property of the type of angular EventEmitter class. This property name becomes custom event name for calling component. @Output decorator can also alias the property name as @Output(alias) and now this alias name will be used in custom event binding in calling component.
Find the @Output decorator using aliasing.

  1. @Output('addData') addEvent = new EventEmitter<any>();

In the above code snippet addData will become custom event name. Now find @Output decorator without aliasing.

  1. @Output() sendMsgEvent = new EventEmitter<string>();

Here sendMsgEvent will be custom event name.

app.component.student.ts
  1. import { Component, Input, Output, EventEmitter } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'student-data',  
  6.     templateUrl: 'app.component.student.html'  
  7. })  
  8.   
  9. export class StudentDataComponent {  
  10.   
  11.     @Input() private Caption1: string = '';  
  12.     @Input() private Caption2: string = '';  
  13.     @Input() private Caption3: string = '';  
  14.     @Input() private Caption4: string = '';  
  15.   
  16.     @Input() private PlaceHolder1: string = '';  
  17.     @Input() private PlaceHolder2: string = '';  
  18.   
  19.     private _model: object = {};  
  20.   
  21.     @Output() private onFormSubmit: EventEmitter<any> = new EventEmitter<any>();  
  22.   
  23.     constructor() {  
  24.   
  25.     }  
  26.   
  27.     private onSubmit(): void {  
  28.         if (typeof (this._model) === "undefined") {  
  29.             alert("Form not Filled Up Properly");  
  30.         }  
  31.         else {  
  32.             alert("Data Is Correct");  
  33.             this.onFormSubmit.emit(this._model);  
  34.         }  
  35.     }  
  36.   
  37.     private onClear(): void {  
  38.         this._model = {};  
  39.     }  
  40. }  
app.component.student.html
  1. <div class="form-horizontal">  
  2.     <strong class="aligncenter">Student Details</strong><br />  
  3.     <div class="row">  
  4.         <div class="col-xs-12 col-sm-2 col-md-2">  
  5.             <span>{{Caption1}}</span>  
  6.         </div>  
  7.         <div class="col-xs-12 col-sm-4 col-md-4">  
  8.             <input type="text" id="txtFName" placeholder="{{PlaceHolder1}}" [(ngModel)]="_model.FName" />  
  9.         </div>  
  10.         <div class="col-xs-12 col-sm-2 col-md-2">  
  11.             <span>{{Caption2}}</span>  
  12.         </div>  
  13.         <div class="col-xs-12 col-sm-4 col-md-4">  
  14.             <input type="text" id="txtLName" placeholder="{{PlaceHolder2}}" [(ngModel)]="_model.LName" />  
  15.         </div>  
  16.     </div>  
  17.     <br />  
  18.     <div class="row">  
  19.         <div class="col-xs-12 col-sm-2 col-md-2">  
  20.             <span>{{Caption3}}</span>  
  21.         </div>  
  22.         <div class="col-xs-12 col-sm-4 col-md-4">  
  23.             <input type="date" id="txtDate"  [(ngModel)]="_model.DOB" />  
  24.         </div>  
  25.         <div class="col-xs-12 col-sm-2 col-md-2">  
  26.             <span>{{Caption4}}</span>  
  27.         </div>  
  28.         <div class="col-xs-12 col-sm-4 col-md-4">  
  29.             <input type="date" id="txtAppDate"  [(ngModel)]="_model.ApplicationDate" />  
  30.         </div>  
  31.     </div>  
  32.     <br />  
  33.     <div class="row">  
  34.         <div class="col-xs-12 col-sm-2 col-md-2">  
  35.         </div>  
  36.         <div class="col-xs-12 col-sm-4 col-md-4">  
  37.         </div>  
  38.         <div class="col-xs-12 col-sm-2 col-md-2">  
  39.             <input type="button" value="Submit" class="btn btn-primary" (click)="onSubmit()" />  
  40.         </div>  
  41.         <div class="col-xs-12 col-sm-4 col-md-4">  
  42.             <input type="button" value="Clear" class="btn btn-primary" (click)="onClear()" />  
  43.         </div>  
  44.     </div>  
  45. </div>  
app.component.output.ts
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'student-form-output',  
  6.     templateUrl: 'app.component.output.html'  
  7. })  
  8.   
  9. export class OutputDataComponent {  
  10.     private _firstNamePlaceHolder: string = 'Enter First Name';  
  11.     private _lastNamePlaceHolder: string = 'Enter Last Name';  
  12.   
  13.     private _model: any;  
  14.   
  15.     private onSaveData(data: any): void {  
  16.         this._model = data;  
  17.         alert("Thank You " + this._model.FName + " for the Registration");  
  18.     }  
  19. }  
app.component.output.html
  1. <div class="form-horizontal">  
  2.     <center> <strong>Students Information Details</strong></center>  
  3.     <br />  
  4.     <student-data [Caption1]="'First Name'" [Caption2]="'Last Name'" [Caption3]="'Date of Birth'" [Caption4]="'Admission Date'"  
  5.                   [PlaceHolder1]="_firstNamePlaceHolder" [PlaceHolder2]="_lastNamePlaceHolder"  
  6.                   (onFormSubmit)="onSaveData($event)"></student-data>  
  7. </div>  
Output 
 



<< Read Part 2 of this article here                                                     Read Part 4 of this article series here >>
 

Next Recommended Readings