Event And Two-Way Binding In Angular 5

We know that Angular provides many ways to bind and display data. Earlier we have seen how can we bind our data using Property Binding, Class Binding, Attribute Binding and Style Binding.

If you are new to binding then please refer to my Data Binding in Angular 5 article before continuing to this article.

In this article, we will go through Event binding, two-way binding and template reference variable.

Event Binding

Firstly, let's see what an event is.  An event is an action recognized by software; i.e., an action taken by a user like a mouse clicks, key presses, etc. To bind these events, Angular provides Event binding, i.e. event binding is used to handle events raised from the DOM like keystrokes, mouse movements, clicks and so on.

Let us understand this with the help of following code,

Create a file named “event-binding.ts” inside the app folder and write the following code,

  1. import { Component } from '@angular/core';  
  2.    
  3. @Component({  
  4.       selector: 'event-binding',  
  5.       template: `<h3 align="center">  
  6.                  Event Binding Example  
  7.                  </h3><br>  
  8.                  <button class="btn btn-primary" (click)="callMyFunction()">  
  9.                     Click Me  
  10.                   </button>`,  
  11.       styleUrls: ['./app.component.css']  
  12. })  
  13. export class EventBindingComponent {  
  14.       title = 'app';  
  15.       callMyFunction() {  
  16.       console.log("My function call");  
  17.     }  
  18. }  

In the above example, we have a button and we want to handle the click event of this button. So, for this, we will call a function “callMyFunction” on button click event. Due to event binding, this button calls the function which writes inside the component and shows a message on console “My function call”.

To see the output, first, you need to put this file's selector (event-binding) inside the “app.component.html” file like this,

  1. <event-binding></event-binding>  

Don’t forget to register our component in app.module.ts file.

The output of the above code,

Angular

Now, we are able to see that our click event works perfectly. But so far I have not been clear whether we can use event binding for this message only.

The answer is no, actually sometimes, we need to get access to the event object that was raised in the event handler, for example, with mouse movement the event object tells us the X and Y position. If you want to access these positions then we need to pass the event object as a parameter like this:

Write the below code in “event-binding.ts” file (it is the same as the previous one, only we pass “$event” object inside the function:

  1. import { Component } from '@angular/core';  
  2.    
  3. @Component({  
  4.       selector: 'event-binding',  
  5.       template: `<h3 align="center">  
  6.                   Event Binding Example  
  7.                   </h3><br>  
  8.                   <button class="btn btn-primary" (click)="callMyFunction($event)">  
  9.                      Click Me  
  10.                   </button>`,  
  11.       styleUrls: ['./app.component.css']  
  12. })  
  13. export class EventBindingComponent {  
  14.       title = 'app';  
  15.       callMyFunction($event) {  
  16.       console.log("Click on Event Object");  
  17.       console.log($event);  
  18.    }  
  19. }     

Now, when you click on the button then you can see all the properties of the event object like this:

Angular

Here, $event object is known to Angular, this object will represents the DOM events. So, you can use any of the properties of $event object.

Let's understand more about the $event, now, I am going to implement “keyup” event on a text box and with the help of event object I will display the value of the text box.

Write the below code in “app.component.ts” file:

  1. import { Component } from '@angular/core';  
  2.    
  3. @Component({  
  4.       selector: 'event-binding',  
  5.       template: `<h3 align="center">  
  6.                   Event Binding Example  
  7.                   </h3><br>  
  8.                   <input type="text" (keyup)="callFunctionOnChange($event)" placeholder="Enter any string" class                  ="form-control w-25 mr-2 float-left">  
  9.                   <button class="btn btn-primary" (click)="callMyFunction($event)">  
  10.                         Click Me  
  11.                   </button>`,  
  12.       styleUrls: ['./app.component.css']  
  13. })  
  14. export class EventBindingComponent {  
  15.          title = 'app';  
  16.          callMyFunction($event) {  
  17.             console.log("Click on Event Object");  
  18.             console.log($event);  
  19.          }  
  20.          callFunctionOnChange($event) {  
  21.             console.log("Key Up Event Activate");  
  22.             console.log($event.target.value);  
  23.          }  
  24.   }  

In the above code, I bound my text box with “keyup” event and call function “callFuncitonOnChange()”. Inside this function we display the value of textbox with the help of $event object, like this:

Angular

Similarly, you can bind a lot of events (change, click, keypress, keyup, etc).

Two-Way Binding

Angular

It is a major feature of Angular. Basically, it's what all we (developers) want. We want that whenever some changes are made into View (UI) then it automatically changes the Model also, which is a little complex to achieve with jQuery.

It can be easily achieved in Angular, this feature is called Two-Way Binding. Two-way binding means changes in the View (UI) can automatically change in the Model (Component's field) and vice-versa. The syntax of two way binding is different from other binding. Angular use parenthesis inside square brackets to achieve this functionality, like [()].

As per other bindings, like attribute binding, it requires "attr.", class binding requires "class.", and style binding requires "styles.", similarly, two-way binding requires "ngModel". Now the question is what is "ngModel"? 

Let's understand with an example. Create a file called “two-way-binding.ts” inside “app folder”, and write the following code:

  1. import { Component } from '@angular/core';  
  2.    
  3. @Component({  
  4.       selector: 'two-way-binding',  
  5.       template: `<h3 align="center">  
  6.                   Two Way Binding Example  
  7.                   </h3><br>  
  8.                   <input type="text" [(ngModel)]="userName" placeholder="Enter your name" 
  9.                    class="form-control w-25 mr-2 float-left">  
  10.                   <p>{{userName}}</p>`,  
  11.       styleUrls: ['./app.component.css']  
  12. })  
  13. export class TwoWayBindingComponent {  
  14.       title = 'app';  
  15. }  

Here in the above code, we will try to implement two-way binding, i.e., whenever a change takes place in the textbox, the property of  “userName” automatically changes and is displayed inside the “<p>” tag.

We are able to achieve this with the help of ngModel, which is a built in directive that is used for implementing two-way binding. This directive is present inside the "form module". By default, form module is not imported in our application. So, you will get this error,

Angular

To get rid of this error we need to import "form module" in our app.component.ts file, like this:

  1. import {FormsModule} from '@angular/forms';  

After importing this file, put “FormModule” inside “imports”.

Now, if you want to see both event binding and two-way-binding in the browser, then put “two-way-binding” selector below the “event-binding” selector in “app.component.html” file, after that the output is,

Angular

 

In the above example, we bind textbox value to a property called “userName” and then display this propety into paragraph tag.

Template Reference Variable

Angular provides one more way to bind data. If you want to access DOM properties of your element then you can use "Template Reference Variable". You can create this variable by two ways i.e.:

By using "ref" keyword, in the below example "myVariable" is a template variable.

  1. <input type="text" placeholder="Click on button" ref-myVariable>  

By using "#" , in the below example "myVariable" is a template variable.

  1. <input type="text" placeholder="Click on button" #myVariable>  

Now, in the above two types of the declaration, "type", "placeholder" and "value" are the "DOM" properties of "input box". So, we can access all these properties with the help of Template Reference variable.

Let's understand this with the help of the example, create “template-reference.ts” file inside “app folder” and write the below code,

  1. import {  
  2.     Component  
  3. } from '@angular/core';  
  4. @Component({  
  5.     selector: 'template-reference-variable',  
  6.     template: `<h3 align="center">Template Reference Variable's Example</h3>     
  7. <br><br>    
  8. <input type="text" placeholder="Click on button" class="form-control w-25 mr-2 float-left" ref-myVariable>    
  9. <button class="btn btn-primary" (click)="setValue(myVariable)">Click Me</button><br><br>    
  10. <div>    
  11. <b>Accessing DOM property 'Type' by template reference variable :- </b>{{myVariable.type}}<br>    
  12. <b>Accessing DOM property 'Placeholder' by template reference variable :- </b>{{myVariable.placeholder}}<br>    
  13. <b>Accessing DOM property 'Value' by template reference variable (click on button) :- </b> {{myVariable.value}}<br>    
  14. </div>`,  
  15.     styleUrls: ['./app.component.css']  
  16. })  
  17. export class TemplateReferenceComponent {  
  18.     title = 'app';  
  19.     setValue(myVariable) {  
  20.         myVariable.value = "Mahesh Verma";  
  21.     }  
  22. }  
In this code, I try to use template reference on button click, i.e. whenever I clicked on a button then it will show “text”, “placeholder” as well as “value” property of DOM.

Now, if you want to see all event binding and two-way-binding and template reference in the browser, then put “template-reference-varible” selector below the “two-way-binding” selector in “app.component.html” file, after that the output is,

Angular

Note

We should not duplicate reference variable name.

Don’t forget to register all components in app.module.ts file. After registering all your components in app.module.ts file, your file looks like this, 

  1. import { TwoWayBindingComponent } from './two-way-binding';  
  2. import { BrowserModule } from '@angular/platform-browser';  
  3. import { NgModule } from '@angular/core';  
  4.   
  5. import {FormsModule} from '@angular/forms';  
  6.   
  7. import { AppComponent } from './app.component';  
  8. import { EventBindingComponent } from './event-binding';  
  9. import { TemplateReferenceComponent } from './template-reference';  
  10.   
  11.   
  12. @NgModule({  
  13.   declarations: [  
  14.     AppComponent,  
  15.     EventBindingComponent,  
  16.     TwoWayBindingComponent,  
  17.     TemplateReferenceComponent  
  18.   ],  
  19.   imports: [  
  20.     BrowserModule,  
  21.     FormsModule,  
  22.   ],  
  23.   providers: [],  
  24.   bootstrap: [AppComponent]  
  25. })  
  26. export class AppModule { }  
I have attached "Sample2WayBinding", a sample project along with this article. This project contains the example of event binding, two-way binding as well as template reference variable, but before running this project install node_modules in this project by using the below command,
  1. npm install  
Conclusion

As we know, Angular supports multiple types of binding such as property, event, class, style, two-way as well as event binding, and after having read this article, we can say that we have the knowledge of all kinds of binding supported by Angular.

I hope it is helpful to you. If you face any problem drop a comment or message to me.