قلاب های چرخه حیات (Lifecycle Hooks)
قلاب چرخه حیات (Lifecycle Hook) یعنی متدی که انگولار در لحظه های مهم صدا می زند. مثلا ایجاد، تغییر ورودی، آماده شدن نما، و نابودی. با این متدها تنظیم می کنی، تغییرها را می بینی، به DOM امن دسترسی می گیری، و درست پاکسازی می کنی.
اصول قلاب های چرخه حیات
از ngOnInit بعد از مقداردهی ورودی ها استفاده کن. تغییر ورودی ها را در ngOnChanges بگیر. به ارجاع های قالب با ngAfterViewInit دست بزن. سپس تایمرها و اشتراک ها را در ngOnDestroy پاک کن.
import { OnInit, OnDestroy, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
export class Demo implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('box') box!: ElementRef<HTMLInputElement>;
intervalId: any;
ngOnInit(): void {
// setup after inputs
}
ngAfterViewInit(): void {
this.box.nativeElement.focus();
}
ngOnDestroy(): void {
clearInterval(this.intervalId);
}
}
// Template: <input #box>
ایجاد و نابودی با *ngIf
نمایش یک کامپوننت، ngOnInit را اجرا می کند. پنهان کردن، ngOnDestroy را اجرا می کند. بنابراین کارها را شروع و سپس متوقف کن.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'child-cmp',
standalone: true,
template: `<p>I am alive!</p>`
})
export class Child implements OnInit, OnDestroy {
intervalId: any;
ngOnInit(): void {
this.intervalId = setInterval(() => {
// work...
}, 1000);
}
ngOnDestroy(): void {
clearInterval(this.intervalId);
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, Child],
template: `
<button (click)="toggle()">Toggle</button>
<child-cmp *ngIf="show"></child-cmp>
`
})
export class App {
show = true;
toggle(): void {
this.show = !this.show;
}
}
bootstrapApplication(App);
واکنش به تغییر ورودی ها با OnChanges
وقتی والد مقدار را عوض می کند، ngOnChanges جزئیات تغییر را می دهد. سپس از SimpleChanges مقدار قبلی و جدید را بخوان.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'child-cmp',
standalone: true,
template: `<p>Prev: {{ prev }} | Curr: {{ curr }}</p>`
})
export class Child implements OnChanges {
@Input() text = '';
prev = '';
curr = '';
ngOnChanges(changes: SimpleChanges): void {
const c = changes['text'];
if (c) {
this.prev = c.previousValue ?? '';
this.curr = c.currentValue ?? '';
}
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, FormsModule, Child],
template: `
<input [(ngModel)]="text" placeholder="type..." />
<child-cmp [text]="text"></child-cmp>
`
})
export class App {
text = '';
}
bootstrapApplication(App);
دسترسی امن به DOM در AfterViewInit
DOM یعنی ساختار عناصر صفحه. سپس بعد از ساخته شدن نما به ارجاع ها دست بزن. بنابراین از @ViewChild همراه ngAfterViewInit استفاده کن.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<input #box />
<div #panel style="width:120px;height:60px;border:1px solid #ccc"></div>
<p>Size: {{ size }}</p>
`
})
export class App implements AfterViewInit {
@ViewChild('box') box!: ElementRef<HTMLInputElement>;
@ViewChild('panel') panel!: ElementRef<HTMLDivElement>;
size = '';
ngAfterViewInit(): void {
this.box.nativeElement.focus();
setTimeout(() => {
const rect = this.panel.nativeElement.getBoundingClientRect();
this.size = `${rect.width}x${rect.height}`;
});
}
}
bootstrapApplication(App);
پاکسازی ایمن در OnDestroy
همیشه منابع را آزاد کن. بنابراین اشتراک ها، تایمرها، و لیسنرها را ببند. این کار نشت حافظه را کم می کند.
// Example teardown pattern
sub?.unsubscribe?.();
clearInterval(intervalId);
removeListener?.();
گام های عملی سریع
- تنظیمات اولیه را در
ngOnInitانجام بده. - ورودی ها را در
ngOnChangesبررسی کن. - DOM را بعد از
ngAfterViewInitدستکاری کن. - همه چیز را در
ngOnDestroyپاکسازی کن.
جمع بندی سریع
- قلاب ها لحظه های کلیدی را پوشش می دهند.
- دسترسی DOM را به تعویق بینداز.
- پاکسازی را فراموش نکن.
- تغییر ورودی را ردیابی کن.
ادامه مسیر: پایپ ها و کلاینت HTTP. همچنین قلاب های چرخه حیات را به عنوان الگوی تمیزکاری استفاده کن.