自定義屬性型 Directive(二):事件處理與 DOM 修改

在 Directive 中監聽事件

要在 Directive 中監聽和處理 DOM 事件,可以使用 host 配置:

import { Directive } from '@angular/core';

@Directive({
  selector: 'a[appSafeLink]',
  standalone: true,
  host: {
    '(click)': 'onConfirmLeavePage($event)',
  },
})
export class SafeLinkDirective {
  constructor() {
    console.log('safe link directive is active!');
  }

  onConfirmLeavePage(event: MouseEvent) {
    const wantsToLeave = window.confirm('Do you want to leave this app?'); // true 或 false

    if (wantsToLeave) {
      return;
    }
    event.preventDefault();
  }
}

上面的例子中:

  • host 配置添加了一個點擊監聽器

  • 當用戶點擊帶有此指令的元素時,將調用 onConfirmLeavePage 方法

  • 事件對象 $event 會作為參數傳入方法

修改 DOM 元素

指令可以直接修改它所附加的 DOM 元素。以下是一個在使用者確認轉跳後,修改 link 行為的例子:

onConfirmLeavePage(event: MouseEvent) {
  const wantsToLeave = window.confirm('Do you want to leave this app?'); // true 或 false

  if (wantsToLeave) {
    const address = (event.target as HTMLAnchorElement).href;
    (event.target as HTMLAnchorElement).href = address + '?from=myApp';
    return;
  }
  event.preventDefault();
}

這個範例中:

  1. 獲取了當前 <a> 標籤的 href 屬性值

  2. 在值後面添加了查詢參數 ?from=myApp

  3. 如果使用者確認離開,則使用修改後的 URL;如果拒絕,則阻止導航行為

TypeScript 類型轉換說明

注意 (event.target as HTMLAnchorElement) 這種寫法。在 TypeScript 中,event.target 的類型是 EventTarget,這是一個通用類型,不包含 href 屬性。

通過類型轉換,我們告訴 TypeScript 這個 event.target 實際上是一個 HTMLAnchorElement,這樣才能安全地訪問 href 屬性。

DOM 修改原理

這個範例中的關鍵是,修改 DOM 元素的 href 屬性發生在瀏覽器執行默認導航行為之前:

  1. 使用者點擊 link

  2. 我們的點擊函數執行,修改了 href 屬性

  3. 處理結束後,瀏覽器使用修改後的 href 值來導航

這是一種巧妙的方式,不需要完全阻止默認行為並自己實現導航邏輯,而是在原生導航發生前修改了導航目標。

Last updated