What is change detection?
Updating the DOM whenever user Data is changed is known as the Change Detection technique. There are two Strategies available for Change Detection in Angular. The default strategy is, everytime user data is changed or manipulated, Angular will run the Change Detector to Update theDOM element. The second one is OnPush(), which we will discuss later in the article.
Angular Framework needs to create a copy of your application's state on the UI by combining the template and the state.
For Example:
Model.ts :
export interface car
{
id:number;
Name:String;
}
Name:{ car.Name } Id: { car.Id }
DOM :
Name:Swift
Id:1
If the template or model file is changed, it's necessary to update the view. This process of syncing the template with the data is called "Change Detection”.Every Frontend Language uses this process, for example, react uses virtual DOM.
Change detection is a process of updating DOM when the state (model orTemplate) is changed.
Read More: Angular Vs Angularjs: Building Accessibility In Angular Applications
How change detection works?
Every Process has its work cycle, for Change Detection it's mainly divided into two parts: The angular side and developer side.
Developer side: Developer's updates application model.
Angular side: Sync the updated state model and re-render the view.
Let’s take a brief look at this process
Step 1: When Developer updates the template page or Data models like changing something in data binding or something.
Step 2: Changes are made in the state of your application, now Angular will detect thechanges.
Step 3: Change detection uses the Tree method to re-render your application/component,ChangeDetection will check every component of your application in tree form from top to bottom to check if any corresponding modelhas changed or not.
Step 4: If there is any change, it will update the component view and re-render it.
It will be easy to understand it with some graphical representation:
Default-strategy1:
You can see Angular components and it Changes Detector (CD) for every component which was created during your application bootstrap process in this image. Those change detectors compare the current value with the previouss one. If ChangeDetector detects the value is changed, it will set Property is Changed==true.
Zone.js
Normally, any asynchronous task is intercepted and tracked by zone.The zone has three phases:
Phase 1: when the zone starts, it is in a stable situation.
Phase 2: It will become unstable if any task is run in the Zone
Phase 3: After the Task is completed it will return to a Stable situation.
Change Detection will be triggered by the angular framework if one of these events is fired:
- Any browser event like a click, keyup, keydown, OnChange, etc.
- setInterval() or setTimeout()
- Any HTTP request using XMLHttpRequest Angular uses its zone called ngZone.There is only one ngZone and in this zone Change detection will be called, only for async operations.
Change Detection strategies
Default ChangeDetection strategy
Angular uses ChangeDetectionStrategy.Defaultas a default change detection strategy. Every time an event is fired like user event, XHR, timer, etc. The default strategy will check every component in the component tree from top to bottom. It will check every component without making any assumption on component's dependencies which may create some issue that's why it's called dirty checking. It can badly influence your application's performance if you have a large application that contains many components.
OnPush()
As we saw in default Change Detection strategy, if you have a large application default strategy will check all component, we will affect your performance.so to overcome that problem you can use OnPush()ChangeDetection strategy.
Let’s understand this with an example:
app.component.ts:
import Component from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
fruits = ['Mengo', 'Orange', 'Banana'];
constructor() { }
addFruit(item) {
this.fruits.push(item);
}
}
Now add some code in app.component.html:
<input><button>Add Fruit
<app-child>
</app-child></button>
Now let’s create a child component:
Go to child >child.component.ts:
<code>import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@Input() data: string[];
constructor() { }
}
</code>
In child > child.component.html:
<app-child><h3>Fruit List</h3>
<ul><li> </li><li>{item}</li></ul>
</app-child>
To change the ChangeDetection strategy in your component you have to add this code in your component ts file:
changeDetection:ChangeDetectionStrategy.OnPush
So your child.component.ts file will look like this:
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush //change in startegy
})
export class ChildComponent {
@Input() data: string[];
constructor() { }
}
So now default ChangeDetector will not get invoked nor will OnPush() because we will have to add a new method which can be called in your child component after that OnPush() ChangeDetector will get called.
addFruit(item)
{
this.fruits = [...this.fruits, item];
}
In that code, we are returning a new food array instead of mutating it.now as you can see angular ran change detection after detecting a new reference to data.
We can understand OnPush easily with graphical representation.
From Angular 7, the OnPush strategy fits well with most of the component, we are using ngrx/store to manage state and it's really useful. For example: if there is a change in data ngrx will bear the responsibility for new references.
We can use ChangeDetectRef to gain full control like:ChangeDetectRef.detectChanges()
For example:We can add update button in our project:
Child.component.ts:
import
Component,
Input,
ChangeDetectorRef,
ChangeDetectionStrategy
from '@angular/core';
@Component(
selector: 'app-child',
templateUrl: './child.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
)
export class ChildComponent
@Input() data: string[];
constructor(private cd: ChangeDetectorRef)
update()
this.cd.detectChanges();
Angular will call the ChangeDetector when we click on Update Data Button.
There are different common available for ChangeDetectorRef like:
ChangeDetectorRef.MarkForCheck():
markForCheck will tell ChangeDetector whenparticular Input is called/rendered.
ChangeDetectorRef.detach()&ChangeDetectorRef.reattach():
you can detach and reattach the method to ChangeDetector using these two methods.
You can understand it in one picture:
ChangeDetectorRefMethods:
Conclusion
There are two strategies available for Change Detection.ChangeDetection.Default, which will check every component from top to bottom in tree formation when ChangeDetector detects any changes.ChangeDetection.OnPush(), this method or component which have OnPush() method described in it, will only be check when any function ormethod of that particular component get called. So, which one should you use?If you have a small project Default strategy is best for you.If you have a large project or a scenario where some of your components doesn’t come in use more often then you should use OnPush() method. We hope you get a clear idea regarding the different ways in which change detection works in Angular.
Top comments (0)