Khi nào chạy change detection ? Nên đặt OnPush ở đâu ?

·

2 min read

cd-cycle_wfdcsk.webp

Khi nào App chạy change detection ?

  1. DOM events (mouse, key, …)
  2. Requests api
  3. Timers (setTimers(), setInterval())
  4. gọi method detectChanges() bằng đối tượng ChangeDetectorRef
  5. Gọi phương thức ApplicationRef.tick()
  6. @input thay đổi
  7. khi có 1 sự kiện DOM, @output
  8. Khi async pipe emit data
  9. Dùng phương thức markForCheck
  10. Chạy code trong ngZone.run()

Khi đặt ChangeDetectionStrategy.OnPush thì các event nào không kích hoạt thay đổi ?

  1. Data đầu vào @Input chỉ thay đổi giá trị mà không phải thay đổi tham chiếu
  2. setTimeout
  3. setInterval
  4. Promise.resolve().then(), Promise.reject().then()
  5. Requests api

Khi đặt ChangeDetectionStrategy.OnPush thì các event nào chạy kích hoạt thay đổi ?

  1. Kích hoạt lại bằng cách thủ công: gọi method detectChanges()
  2. Gọi phương thức ApplicationRef.tick()
  3. Tham chiếu đầu vào @input thay đổi
  4. Chính component này hoặc 1 trong các component con của nó kích hoạt 1 sự kiện
  5. Khi async pipe emit data
  6. Dùng phương thức markForCheck

Nên đặt ChangeDetection OnPush ở đâu ?

  1. Ở các component được định nghĩa trong router: thường các component này là 1 màn hình, data của nó do nó tự call về chứ không phụ thuộc vào thằng khác, nên không có lí do gì để nó chạy ChangeDetection, ngoài ra khi đặt OnPush ở đây thì các component con của nó cũng không chạy ChangeDetection, bởi vì các component con của nó hầu như chỉ phụ thuộc vào data từ component này
  2. Component là 1 màn hình hoặc component không phụ thuộc data bên ngoài nó
  3. Đặt OnPush trong component có chứa nhiều cấp hoặc chứa nhiều component con và đặt trong các component con của nó

Cẩn thận

  1. Khi dùng OnPush mà lại thay đổi data ở ngAfterViewInit thì sẽ có lỗi ExpressionChangedAfterCheckedError, data mới nhất sẽ không được render, lỗi này chỉ sảy ra ở develop mode nên cần bật console để check
  2. Phải control được khi nào cần chạy changeDetection để kích hoạt lại, nếu không có thể xảy ra lỗi do data mới không được cập nhật