How to detect when an @Input() value changes in Angular?
- Approach: @Input() can be used in two ways:
- Two-way bindings with @Input()
- One-way binding with ngOnChange() and @Input()
- First, we will look at Two-way binding.
Two-way binding combines input and output in a single notation using ngModel directive. The notation for two-way binding is [()].
Here is how we will implement two-way binding. We have a component FormComponent (parent) and ChildComponent (child). When the user enters anything in the text input field of the parent component, the child component detects it.
Implementation of Two-way binding:
Here we are creating a parent component and adding child to it. form.component.html In child component, we are passing a property 'message' which holds the value bound by the input element using ngModel. Here is the FormComponent class: form.component.tshtml <div style="border: 1px solid rgb(46, 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>
This change will get reflected in child component. The 'message' will get displayed here. Here is the code for that: child.component.htmljavascript 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; }
In the ChildComponent class, we will import Input so as to detect the message from FormComponent class. child.component.tshtml <div style="border:1px solid rgb(53, 71, 131); width:30vw; height: 12vh; padding: 10px 10px; margin:20px"> <h4> You entered <span>{{message}}</span></h4> </div>
This was all about the Two-way binding. Now let's see how to use One-way binding.javascript 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() { } }
Implementation of One-way binding with ngOnChange() and @Input():
Here is how we will use ngOnChange() to bind the input. The code for childComponent will be same as was the case with two-way binding. However, the FormComponent will have onChange() method getting called. Here is the code for that. form.component.html Notice the difference between this component and previous code showing Two-way binding. Here, ngModel and ngModelChange both are bound with input element. Since we are using onChange(), we do not need to use @Input() to detect the change. form.component.tshtml <div style="border: 1px solid rgb(46, 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>
javascript 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; } }