The difference in two-way data binding in Angular 2 and angularJS
Data Binding is a feature of modern frameworks which synchronizes the data displayed in the view and that holds with the model.
Without data binding, a developer would have to write code that constantly synchronizes the view to the model and vice versa. A JQuery developer would tell you how painful this can get when the app starts to grow.
However most frameworks implement one-way data binding, through which the changes in the model are propagated to the view but any changes the user makes to the view have to be manually updated to the model, of course by writing a piece of code that would do the synchronization.
In this article we will see, how Angular 2 takes care of data binding and how it implements two-way data binding and its difference from Angular 1.
Lets first have a look at how Angular 1 took care of two-way data binding.
Two-way Data Binding in AngularJS
One of the core feature and a wow factor of Angular 1 was two-way data binding. In which any changes that occur to the model are propagated to the view, and any changes user makes to the view are updated to the model. This eliminated much of the code a developer has to write to synchronize the view-model.
That being said, the way in which AngularJS implemented two-way data binding, raised a few doubts related to performance. To keep the model-view in sync Angular 1 used a concept called dirty checking. Any changes in the $scope properties or the DOM would trigger a digest cycle. Digest Cycle was responsible for keeping the view-model in sync. Whenever we made any changes to the data or DOM from outside Angular, we would have to run the $apply function in order to run the $digest cycle manually.
In Angular 1 neither the DOM nor the model had the authority of the data. Any changes in these would trigger the $digest cycle. But sometimes there were possibilities that, the DOM and the model wouldn’t agree upon the data, this would trigger an infinite $digest loop where the DOM would cause an update in the model and the model would subsequently update the DOM and the cycle would continue. To counter this challenge, there was a limit to the number of times the digest cycle will run consecutively, about around 5 or 6 times, after which Angular would throw out an error. Seems kinda dirty.
Data Binding in Angular 2
Angular 2 deals with the problem that Angular 1 faced by setting a clear authority of the data. But before we look into two-way data binding in Angular 2, we must first understand how one-way data binding works.
Data binding in Angular 2 can broadly be classified into two types.
- Event Binding
- Property Binding
A state of an application changes when there is some API fetch, a timeout or an interval event and when the user interacts with the application meaning click on some element or type something etc.
In the first three cases, directly the model is changed, and to reflect the changed model into the DOM we can use property bindings or interpolation. However in the final case when the user interacts with the application we may have to propagate the updated data into the model, this is done via the event binding.
Event Binding syntax
A click event on the button will fire up the
Property Binding Syntax
Depending upon the value of
[hidden]property will be set to the
Two-way Data binding in Angular 2
Angular 2 does not provide any direct mechanism to implement two-way data binding. Shocked? No worries, we can still achieve it by combining event and property binding.
In short two-way data binding in Angular 2 is a combination of event and property binding on the same element.
<input [value]="myComponent.firstName" (input)="myComponent.firstName=$event.target.value" >
Here if you see we are setting the property
firstName, and we also have an
(input) event that will update the value of the
firstName to the input value.
This can also be achieved by using
[ngModel] input property and
(ngModelChange) output property, these two directives simply allow to set the desired property and listen to the required user events on components.
<input [ngModel]="myComponent.firstName" (ngModelChange)="myComponent.firstName=$event" >
Angular 2 also provides syntax sugar and another directive
[(ngModel)] to implement two-way data binding, so instead of the above, you could just do.
<input [(ngModel)]="myComponent.firstName" />
To remember that the round brackets are wrapped inside the square ones and not the other way around, the angular team calls two-way data binding as a “Box of Bananas“.
Note: This article is written for Angular 2.0 beta. The Angular 2 repo is subjected to change, if you find any discrepancies please write to us about it and if possible suggest the fixes
How is it different from Angular 1?
The way in which this is different from Angular 1 is worth noting. Remember we mentioned above that how in Angular 1 nothing has a clear authority for the data and how this could lead to multiple iterations of digest loop.
Angular 2 tackles this problem by clearly giving the model the authority of the data. Meaning whatever is with the model is truthy and that the DOM is just a replica of the Model.
So a change in the model will reflect in the DOM. But if there is a change in the DOM (by a user interaction), the data is propagated to the model via the event, thereby updating the model and thus the DOM. This approach gives a significant performance advantage to Angular 2 over Angular 1. See the diagram below for clarification.
One last thing I want to mention in this article is references. References are cool as they allow inter-component interaction via the template syntax. See example below.
<phone-component #phone ></phone-component> <button (click)="phone.call()">Call</button>
So using a reference to a component you can call methods on that component from other components directly in the template.