Angular Material 17+ 高階教程 – Observers

兴杰發表於2024-05-07

前言

Observers 是 Angular Material 對遊覽器原生 MutationObserver 的上層封裝。主要用於監聽 add/remove Node。

不熟悉的朋友可以先看這篇 DOM – MutationObserver

ContentObserver

ContentObserver 是一個 Root Service Provider,類似 class MutationObserver。

它的用法非常直觀

export class TempComponent {
  constructor() {
    const contentObserver = inject(ContentObserver);
    const hostElement = inject(ElementRef);
    const mutationRecords$ = contentObserver.observe(hostElement);
    afterNextRender(() => {
      mutationRecords$.subscribe(records => console.log(records));
    });
  }
}

inject ContentObserver,然後 observe Element / ElementRef,

返回 RxJS Observable<MutationRecord[]>。

subscribe 後它就開始監聽了。

逛一逛原始碼

ContentObserver 的原始碼在 observe-content.ts

我們直接從 ContentObserver.observe 看起吧。

它不支援 observe document 哦。

_observeElement 方法

這個工廠函式長這樣

每一次執行 contentObserver.observe 內部就會呼叫 MutationObserverFactory.create 建立一個 MutationObserver 物件。

繼續

options 是寫死的,我們無法配置,它會監聽子孫層 add/remove element 和 text node。

回到 ContentObserver.observe

shouldIgnoreRecord 函式

主要就是無視 comment,很多 comment 都是 Angular 自己要用的,比如 <ng-container />, <ng-template> 這些都是 comment,開發者一般上是不想監聽這些的,所以它過濾掉。

總結:

  1. 每一次 observe 都會建立一個原生 MutationObserver 物件

  2. wrap RxJS Observable

  3. options 寫死,監聽子孫 add/remove element 和 text node (attribute 變化它監聽不到哦)

  4. 過濾掉 comment add/remove 的 MutationRecord,因為這些多半是 Angular 專用的

CdkObserveContent 指令

CdkObserveContent 指令內部用的是 ContentObserver,所以它又只是一個上層封裝而已。

import ObserversModule

然後 apply 指令

<div cdkObserveContent 
  (cdkObserveContent)="handleContentChanges($event)" 
  [cdkObserveContentDisabled]="false" 
  [debounce]="100">
</div>

它可以調一些小配置,比如 disabled,debounce 是 RxJS 的 debounceTime

$event 就是 MutationObserver 釋出的 MutationRecord[]。

目錄

上一篇 Angular Material 17+ 高階教程 – Overlay

下一篇 TODO

想檢視目錄,請移步 Angular 17+ 高階教程 – 目錄

相關文章