Angular Hook Life Cycle:
1.ngOnChanges
2.ngOnInit
3.ngDoCheck
4.ngAfterContentInit
5.ngAfterContentChecked
6.ngAfterViewInit
7.ngAfterViewChecked
8.ngOnDestroy
ngOnChanges
ngOnChanges triggers following the modification of @Input bound class members. Data bound by the @Input() decorator come from an external source. When the external source alters that data in a detectable manner, it passes through the @Input property again.
With this update, ngOnChanges immediately fires. It also fires upon initialization of input data. The hook receives one optional parameter of type SimpleChanges. This value contains information on the changed input-bound properties.
Example
import { Component, Input, OnChanges } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<h3>Child Component</h3>
<p>TICKS: {{ lifecycleTicks }}</p>
<p>DATA: {{ data }}</p>
`
})
export class ChildComponent implements OnChanges {
@Input() data: string;
lifecycleTicks: number = 0;
ngOnChanges() {
this.lifecycleTicks++;
}
}
@Component({
selector: 'app-parent',
template: `
<h1>ngOnChanges Example</h1>
<app-child [data]="arbitraryData"></app-child>
`
})
export class ParentComponent {
arbitraryData: string = 'initial';
constructor() {
setTimeout(() => {
this.arbitraryData = 'final';
}, 5000);
}
}
ngOnInit
ngOnInit fires once upon initialization of a component’s input-bound (@Input) properties. The next example will look similar to the last one. The hook does not fire as ChildComponent receives the input data. Rather, it fires right after the data renders to the ChildComponent template.
Example:
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<h3>Child Component</h3>
<p>TICKS: {{ lifecycleTicks }}</p>
<p>DATA: {{ data }}</p>
`
})
export class ChildComponent implements OnInit {
@Input() data: string;
lifecycleTicks: number = 0;
ngOnInit() {
this.lifecycleTicks++;
}
}
@Component({
selector: 'app-parent',
template: `
<h1>ngOnInit Example</h1>
<app-child [data]="arbitraryData"></app-child>
`
})
export class ParentComponent {
arbitraryData: string = 'initial';
constructor() {
setTimeout(() => {
this.arbitraryData = 'final';
}, 5000);
}
}
ngDoCheck
ngDoCheck fires with every change detection cycle. Angular runs change detection frequently. Performing any action will cause it to cycle. ngDoCheck fires with these cycles. Use it with caution. It can create performance issues when implemented incorrectly.
ngDoCheck lets developers check their data manually. They can trigger a new application date conditionally. In conjunction with ChangeDetectorRef, developers can create their own checks for change detection.
Example:
import { Component, DoCheck, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-example',
template: `
<h1>ngDoCheck Example</h1>
<p>DATA: {{ data[data.length - 1] }}</p>
`
})
export class ExampleComponent implements DoCheck {
lifecycleTicks: number = 0;
oldTheData: string;
data: string[] = ['initial'];
constructor(private changeDetector: ChangeDetectorRef) {
this.changeDetector.detach(); // lets the class perform its own change detection
setTimeout(() => {
this.oldTheData = 'final'; // intentional error
this.data.push('intermediate');
}, 3000);
setTimeout(() => {
this.data.push('final');
this.changeDetector.markForCheck();
}, 6000);
}
ngDoCheck() {
console.log(++this.lifecycleTicks);
if (this.data[this.data.length - 1] !== this.oldTheData) {
this.changeDetector.detectChanges();
}
}
}
ngAfterContentInit
ngAfterContentInit fires after the component’s content DOM initializes (loads for the first time). Waiting on @ContentChild(ren) queries is the hook’s primary use-case.
@ContentChild(ren) queries yield element references for the content DOM. As such, they are not available until after the content DOM loads. Hence why ngAfterContentInit and its counterpart ngAfterContentChecked are used.
import { Component, ContentChild, AfterContentInit, ElementRef, Renderer2 } from '@angular/core';
@Component({
selector: 'app-c',
template: `
<p>I am C.</p>
<p>Hello World!</p>
`
})
export class CComponent { }
@Component({
selector: 'app-b',
template: `
<p>I am B.</p>
<ng-content></ng-content>
`
})
export class BComponent implements AfterContentInit {
@ContentChild("BHeader", { read: ElementRef }) hRef: ElementRef;
@ContentChild(CComponent, { read: ElementRef }) cRef: ElementRef;
constructor(private renderer: Renderer2) { }
ngAfterContentInit() {
this.renderer.setStyle(this.hRef.nativeElement, 'background-color', 'yellow')
this.renderer.setStyle(this.cRef.nativeElement.children.item(0), 'background-color', 'pink');
this.renderer.setStyle(this.cRef.nativeElement.children.item(1), 'background-color', 'red');
}
}
@Component({
selector: 'app-a',
template: `
<h1>ngAfterContentInit Example</h1>
<p>I am A.</p>
<app-b>
<h3 #BHeader>BComponent Content DOM</h3>
<app-c></app-c>
</app-b>
`
})
export class AComponent { }
No comments:
Post a Comment