電腦螢幕上的程式碼編輯畫面與藍色原子標誌,象徵 Angular 自訂指令開發

← INSIGHTS & PERSPECTIVES | 前端開發

Angular Attribute Directive 屬性指令教學:自訂 appHighlight 高亮效果

用 Angular 自訂屬性指令(Attribute Directive)改變元素外觀與行為,逐步建立 appHighlight 高亮directive,搭配 @Input 傳入參數與 @HostListener 監聽滑鼠事件

Directive 分為結構型和屬性型兩種,這一篇我要先介紹屬性型的 Directive(Attribute Directive)。我會用一個滑鼠懸停就改變背景色的高亮範例,一步步帶你建立自己的directive,最後再加上`@Input`讓使用者自訂高亮顏色。

Angular 的 directive 有哪三種?

Angular 有三種 directive:

  • 元件(Component):包含template的directive。
  • 結構指令(Structural Directive):通過添加和刪除DOM元素來更改DOM佈局(如`ngFor`、`ngIf`)。
  • 屬性指令(Attribute Directive):改變元素、組件或其他指令的外觀或行為(如`ngStyle`)。

本篇的範例請見:Attribute Directive example / download example

怎麼建立一個簡單的屬性型 directive?

一個 directive 最少需要一個帶有`@Directive`宣告的檔案,告訴 angular 該如何識別這個 directive。

我會用一個 highlight 的 directive 範例來解說:當用戶將鼠標懸停在該元素上時,設置元素的背景色。你可以像這樣應用它:

```html

Highlight me!

```

接下來就一步步創立這個 directive。首先用 cli 創立一個新的 directive:

```bash

ng generate directive highlight

```

會看到 cli 自動建立了兩個新的檔案:

ng generate directive 自動建立的檔案

產生的`src/app/highlight.directive.ts`檔案內容如下:

```js

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

@Directive({

selector: '[appHighlight]'

})

export class HighlightDirective {

constructor() { }

}

```

當我們 import 了`Directive`後,就可以在檔案內使用`@Directive`來設定 directive 的 CSS attribute selector。方括弧`[]`可以讓它成為一個屬性選擇器。在這邊為什麼取為`appHighlight`而不是`highlight`?是為了避免與現有的 html 指令衝突。建議最好在所有的 directive 前面加上前綴字,以方便識別這是哪邊來的屬性——如果沒有前綴字,很容易發生難以識別的錯誤。

怎麼用 ElementRef 直接修改 DOM 樣式?

接著看`src/app/highlight.directive.ts`的內容:

```js

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

@Directive({

selector: '[appHighlight]'

})

export class HighlightDirective {

constructor(el: ElementRef) {

el.nativeElement.style.backgroundColor = 'yellow';

}

}

```

可以看到在建構子的地方傳入了 ElementRef,並使用`el.nativeElement`直接修改 DOM 元素的背景顏色。

若希望 directive 能夠接收使用者事件,可以加載`HostListener`:

```js

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({

selector: '[appHighlight]'

})

export class HighlightDirective {

constructor(private el: ElementRef) { }

@HostListener('mouseenter') onMouseEnter() {

this.highlight('yellow');

}

@HostListener('mouseleave') onMouseLeave() {

this.highlight(null);

}

private highlight(color: string) {

this.el.nativeElement.style.backgroundColor = color;

}

}

```

顯示的結果如下圖:

滑鼠懸停時背景變黃色的高亮效果

當然,也可以通過標準的 JavaScript 來訪問 DOM,並手動添加事件監聽器。但這種方法至少有三個問題,是不被建議的:

  • 需正確的監聽到各種平台的事件
  • 當要 destroy 這個 directive 時要手動移除事件
  • 直接操作 DOM API 不是好的方式

怎麼輸入參數至 directive?

首先要先 import 所需的`Input`:

```js

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

```

然後宣告所要輸入的變數:

```js

@Input() highlightColor: string;

```

那麼在使用 directive 傳入參數的方式有下面幾種:

```html

Highlighted in yellow

Highlighted in orange

Highlight me!

```

完整範例:讓使用者自己選高亮顏色

下面這個範例是使用上面自製的 directive,讓使用者選擇 highlight 的顏色。template 檔案內容如下:

```html

My First Attribute Directive

Pick a highlight color

<input type="radio" name="colors" (click)="color='lightgreen'">Green

<input type="radio" name="colors" (click)="color='yellow'">Yellow

<input type="radio" name="colors" (click)="color='cyan'">Cyan

Highlight me!

```

component 內容如下:

```js

export class AppComponent {

color: string;

}

```

最後結果如下圖:

使用者點選顏色後文字背景即時改變

延伸閱讀

常見問題

QAttribute Directive 和 Structural Directive 有什麼差別?

Attribute Directive 負責改變元素的外觀或行為,例如`ngStyle`或自訂的高亮效果;Structural Directive 則是透過新增或移除 DOM 元素來改變版面結構,例如`ngIf`和`ngFor`。簡單說,前者改「樣子」,後者改「有沒有」。

Q為什麼 directive 的 selector 要加前綴字?

加上像`app`這樣的前綴字(如`appHighlight`)可以避免與現有 HTML 屬性或其他directive衝突,也能一眼看出這個屬性來自哪個應用程式,否則很容易發生難以識別的錯誤。

Q為什麼不直接用 JavaScript 操作 DOM 加事件監聽器?

手動監聽至少有三個問題:需要正確監聽各種平台的事件、directive 銷毀時要記得手動移除監聽器,而且直接操作 DOM API 本身就不是 Angular 建議的做法。用`@HostListener`可以讓 Angular 代管這些細節。

QElementRef 是什麼?

`ElementRef`是對宿主 DOM 元素的包裝,透過`el.nativeElement`可以拿到原生的 DOM 元素,進而直接修改它的樣式或屬性,例如範例中設定`backgroundColor`。

Q@Input() 在 directive 裡怎麼用?

在 directive 類別中用`@Input()`宣告屬性(如`highlightColor`)後,就能在 template 用靜態屬性`highlightColor="yellow"`、綁定字串`[highlightColor]="'orange'"`,或直接綁定到selector`[appHighlight]="'orange'"`三種方式傳值。

參考資料

最後更新

2026-08-28(原文發布於 2018-01-01,本文保留原始筆記內容並補上 GEO 結構。)

關於作者 {#author}

Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。

首次發布:2018-01-01