Getting started
@Input() is the decorator used for the binding property as an input. It is generally used for passing the data. In other words, @input() is used for data transfer between different components or from parent to child component. It is associated with the DOM element. Whenever the DOM element value changes, the value gets automatically updated with the new changed value. In this blog, we will find out how we can use it exactly. Sounds pretty interesting right, come let’s figure it out in more detail.
Source: giphy
Approach:
In two ways, @Input() can be used:
- Two-way bindings with @Input()
- One-way binding with ngOnChange() and Input().
First of all, let’s understand the two-way binding. Using two-way binding, the input and output are combined in a single notation using ngModel directive. The notation looks like this: [ ( ) ]. Now, let’s go through an example for better clarity:
In this type of binding, we are having two components: FormComponent(parent) and
ChildComponent(child). When anything is entered in the text input field of the parent component, the child component deflects it.
<div style="border: 1px solid rgb(48, 93, 194); height: 25vh; width: 35vw; padding: 10px 10px; margin: 20px;" > <b>Type here : </b> <input type="text" [(ngModel)]='text' /> <child [message]='text'></child> </div> |
In the child component, a ‘message’ property is passed which carries the property hold by the input elementusing ngModel. The formComponent class looks like:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.scss'] }) export class FormComponent implements OnInit { constructor() { } ngOnInit(): void { } public text : string; } |
All the changes done will get reflected in the child component. The message will also get reflected. Let’s name the file as child.componenet.html.
<div style="border:1px solid rgb(54, 71, 131); width:30vw; height: 12vh; padding: 10px 10px; margin:20px"> <h4> You entered <span>{{message}}</span></h4> </div> |
Now, in the ChildComponent class, input is imported for detecting the message from FormComponent class.
child.component.ts
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'child', templateUrl: './child.component.html', styleUrls: ['./child.component.scss'] }) export class ChildComponent { //message will detect the input from FormComponent. @Input() message:string; constructor() { } } |
This was all about two-way binding. Now let’s check about one-way binding.
Using one-way binding, we will learn how we can use ngOneChange() to bind the input. The code looks exactly similar with two-way bonding. The only difference is FormComponent will be having a onChange() method getting called. The code looks like:
form.component.html
<div style="border: 1px solid rgb(45, 93, 194); height: 25vh; width: 35vw; padding: 10px 10px; margin: 20px;" > <b>Type here : </b> <input type="text" [ngModel]='text' (ngModelChange)='onChange($event)' /> <child [message]='text'></child> </div> |
From both the codes, one shown above and the previous one using two-way binding, ngModel and ngModelChange both are bounded to input element. And as we are using onChange(), we don’t need to use @input() for detecting the changes.
form.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.scss'] }) export class FormComponent implements OnInit { constructor() { } ngOnInit(): void { } public text : string; onChange(UpdatedValue : string) :void { this.text = UpdatedValue; } } |