Angular Lifecycle Hooks: ngOnInit, ngOnChanges, ngOnDestroy

Lifecycle Hooks คือ method พิเศษที่ Angular เรียกตามช่วงชีวิตของ Component ตั้งแต่สร้าง รับข้อมูล ตรวจการเปลี่ยนแปลง แสดง View จนถึงถูกทำลาย

Timeline/ประวัติศาสตร์

%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
  subgraph Era1["ยุค Page Load / Browser Era"]
    A["DOMContentLoaded
รอหน้าโหลด"] end subgraph Era2["ยุค Component / Angular Era"] B["ngOnInit
เริ่มต้น Component"] C["ngOnChanges
รับ Input ใหม่"] end subgraph Era3["ยุค Resource Management / Cleanup Era"] D["ngAfterViewInit
View พร้อมใช้"] E["ngOnDestroy
คืนทรัพยากร"] end A --> B --> C --> D --> E

Hooks ที่ใช้บ่อย

ตารางลำดับ Lifecycle Hooks

ลำดับ Hook เรียกเมื่อใด ใช้งานเหมาะกับ
1 ngOnChanges @Input() เปลี่ยน คำนวณใหม่จาก Input
2 ngOnInit สร้าง Component แล้ว ดึงข้อมูลเริ่มต้น
3 ngDoCheck ทุก Change Detection ตรวจ custom change
4 ngAfterViewInit View พร้อม เข้าถึง ViewChild
5 ngOnDestroy ก่อนถูกลบ unsubscribe/clear timer

Mermaid Diagram: Lifecycle Flow

%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
  A["สร้าง Component
Create"] --> B["รับ Input ใหม่
ngOnChanges"] B --> C["เริ่มต้นครั้งเดียว
ngOnInit"] C --> D["ตรวจการเปลี่ยนแปลง
ngDoCheck"] D --> E["View พร้อมใช้งาน
ngAfterViewInit"] E --> F["ทำงานระหว่างใช้งาน
Runtime"] F --> G["ทำลาย Component
ngOnDestroy"]

สมการคณิตศาสตร์: การลด Memory Leak

L = S - U

Code Example

// timer.component.ts
// Component นี้สาธิต ngOnInit และ ngOnDestroy
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { interval, Subscription } from 'rxjs';

@Component({
  selector: 'app-timer',
  template: `
    <h2>{{ title }}</h2>
    <p>วินาทีที่ผ่านไป: {{ seconds }}</p>
  `
})
export class TimerComponent implements OnChanges, OnInit, OnDestroy {
  @Input() title = 'Timer';
  seconds = 0;
  private timerSub?: Subscription;

  // เรียกเมื่อ @Input title เปลี่ยนค่า
  ngOnChanges(changes: SimpleChanges): void {
    if (changes['title']) {
      console.log('Title changed:', changes['title'].currentValue);
    }
  }

  // เรียกครั้งเดียวหลัง Component สร้างเสร็จ
  ngOnInit(): void {
    this.timerSub = interval(1000).subscribe(() => {
      this.seconds += 1;
    });
  }

  // เรียกก่อน Component ถูกทำลาย ใช้คืนทรัพยากร
  ngOnDestroy(): void {
    this.timerSub?.unsubscribe();
  }
}

// ตัวอย่างการใช้งาน:
// <app-timer title="เวลาเรียน Angular"></app-timer>

กิจกรรมท้ายบท

กลับสัปดาห์ที่ 7