hostDirectives
問題情境
假設我們想要在應用程式的多個元素上實現相同的行為(如記錄點擊事件),傳統方法會需要在每個元素上手動添加指令(Directive)。這種做法會使標記變得冗長,且難以維護。
建立基本的 Log 指令
首先,我們創建一個基本的 LogDirective
,用來記錄元素的點擊事件:
import { Directive, ElementRef, inject } from '@angular/core';
@Directive({
selector: '[appLog]',
standalone: true,
host: {
'(click)': 'onLog()',
},
})
export class LogDirective {
private elementRef = inject(ElementRef);
onLog() {
console.log('CLICKED');
console.log(this.elementRef.nativeElement);
}
}
這個指令會:
監聽元素的點擊事件
在控制台輸出「CLICKED」訊息
輸出被點擊元素的原生 DOM 節點
傳統使用方式
傳統上,我們需要在每個想要記錄的元素上添加 appLog
指令:
<main>
<app-learning-resources appLog />
<hr />
<app-auth appLog/>
<p appLog *appAuth="'admin'" class="protected-content admin">
Only admins should see this!
</p>
<p *appAuth="'user'" class="protected-content unauthenticated">
Regular users should see this!
</p>
<p *appAuth="'guest'" class="protected-content authenticated">
Guest users should see this!
</p>
</main>
同時,還需要在使用的組件中導入這個指令:
import { LogDirective } from './log.directive';
@Component({
// ...
imports: [LogDirective],
// ...
})
export class SomeComponent {}
這種方式的缺點:
需要在每個元素上重複添加相同的指令
HTML 變得冗長
如果要更改行為,需要修改多個地方
使用 hostDirectives
Angular 提供了 hostDirectives
選項,讓我們能夠將指令與組件「合併」,這樣組件自身會自動應用指定的指令:
import { LogDirective } from '../log.directive';
@Component({
selector: 'app-auth',
standalone: true,
imports: [],
templateUrl: './auth.component.html',
styleUrl: './auth.component.css',
hostDirectives: [LogDirective],
})
export class AuthComponent {}
重要特性:
組件級別的應用:使用
hostDirectives
會將指令應用於組件本身的宿主元素,而不是組件內的所有元素。簡化標記:不需要在 HTML 中添加額外的屬性指令。
集中管理:可以在組件定義中集中管理多個指令。
注意事項:
hostDirectives
應用的指令只影響組件的宿主元素(即<app-auth>
標籤本身),而不會影響組件內部的所有元素。點擊組件內的子元素不會觸發
LogDirective
,除非事件冒泡到宿主元素。如果需要在組件內的多個元素上應用相同的指令,仍然需要在各個元素上手動添加或使用其他策略。
高級用法:指令導出與輸入屬性
hostDirectives
還支持導出指令的屬性和方法,以及設置指令的輸入屬性:
@Component({
// ...
hostDirectives: [
{
directive: LogDirective,
inputs: ['level', 'format'],
outputs: ['logged']
}
],
})
export class AuthComponent {}
這種方式允許:
通過
inputs
配置指令的輸入屬性通過
outputs
暴露指令的輸出事件
總結
hostDirectives
是 Angular 提供的一種機制,用於將指令直接應用於組件的宿主元素,從而減少模板中的冗餘標記並提高代碼的可維護性。它特別適用於需要在多個組件上應用相同行為的場景,例如日誌記錄、權限控制或樣式增強等。
Last updated