iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0

指令是指在 Angular 應用程式中,可以改變元素的設定、樣式及添加附加行為的類別,所以我們前面提到的元件本質上也是一種指令,只是帶有模板和樣式。
而不含模板的指令,則有兩種主要類型:屬性指令和結構指令

屬性指令 Attribute directives

主要用來改變元素的外觀或行為,但不會新增或移除元素,改變到 DOM 結構。
最常見的內建屬性指令有: ngClassngStylengModel

在過去 ngClass、ngStyle 常用來支援多個類別或樣式的動態切換,但在 class、style 繫結也可以達成相同效果後,基本上可以直接使用 class、style 繫結來取代 ngClass、ngStyle。

結構指令 Structural Directives

主要用來改變 DOM 結構,透過新增或移除元素來改變畫面內容。
會根據條件動態新增或移除 HTML 元素,語法通常加上 *,如:<div *ngIf="isLogin"></div>
例如:*ngIf*ngFor*ngSwitch

*ngIf*ngFor*ngSwitch 預計在 Angular 22 後移除,建議改用 @if@for@switch

自定義指令

自定義指令除了根據需求創建自定義的屬性指令或結構指令之外,也可以透過注入服務來擴展指令的功能。

快速生成指令

Angular CLI 的指令,自動產生一個指令檔案。

ng generate directive <directive-name>
ng g d <directive-name>

使用 @Directive 裝飾器來定義自訂指令。

  • selector:會使用屬性選擇器的方式來綁定指令。
  • standalone: true:表示這是一個獨立的指令,不需要包含在任何 NgModule 中,和元件時介紹相同
  • host:用於綁定指令需執行的事件。

指令範例

屬性指令範例

通常會搭配 ElementRef 來操作 DOM 元素,改變元素的樣式。
或是在事件處理函式中,加入其他邏輯,例如:點擊連結後,目標網址會添加 URL 參數。

@Directive({
  selector: '[appHoverColor]',
  host: {
    '(mouseenter)': 'onMouseEnter()',
    '(mouseleave)': 'onMouseLeave()',
  },
})

export class HoverColorDirective {
  color = input('red', { alias: 'appHoverColor' }); // 將 input 名稱和屬性指令對應
  private el = inject<ElementRef<HTMLElement>>(ElementRef);

  onMouseEnter() {
    this.el.nativeElement.style.color = this.color(); // nativeElement 代表被綁定的元素
  }
  onMouseLeave() {
    this.el.nativeElement.style.color = '';
  }
}

ElementRef:ElementRef 是 Angular 中的一個類別,用於直接操作 DOM 元素。

設定完指令後,就可以在模板中使用

<p appHoverColor="blue">

結構指令範例

TemplateRef:可以取得模板內容的參考。

ViewContainerRef: 可以取得容器在所屬檢視中位置的錨點元素。

  • 可以用來在指令中動態插入或移除模板片段。

通常 ViewContainerRefTemplateRef 一起使用,以便在指令中動態渲染模板內容。

export class AuthDirective {
  user = input.required<Tuser>({ alias: 'appAuth' });
  loginService = inject(Login);
  private templateRef = inject(TemplateRef);
  private viewContainerRef = inject(ViewContainerRef);
  
  constructor() {
    effect(() => {
      if (this.loginService.login() === 'admin') {
        this.viewContainerRef.createEmbeddedView(this.templateRef); // 將模板內容插入到檢視中位置的錨點元素
      } else {
        this.viewContainerRef.clear();
      }
    });
  }
} 

export type Tuser = 'admin' | 'guest';

* 是 Angular 結構型指令的語法糖,實際上 Angular 會將其轉換為 <ng-template> 元素,並將指令應用於該模板。

<div *appAuth="'admin'">admin 會顯示</div>
<!--實際上 Angular 會轉換-->
<template appAuth="'admin'">
  <div>admin 會顯示</div>
</template>

結論

今天介紹了 Angular 中的指令的基礎用法,包括屬性指令和結構指令。明天會介紹 pipes 應用。


上一篇
Day 19 - 元件生命週期
下一篇
Day 21 - Pipes
系列文
Angular 新手練功日誌:從零到職場冒險23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言