自定義屬性型 Directive(三):輸入參數與進階用法
為 Directive 添加輸入參數
Directive 和 component 一樣,可以接收輸入參數來增強其可重用性。
基本輸入用法
可以使用 input()
函數來定義輸入屬性:
import { Directive, input } from '@angular/core';
@Directive({
selector: 'a[appSafeLink]',
standalone: true,
host: {
'(click)': 'onConfirmLeavePage($event)',
},
})
export class SafeLinkDirective {
// 'myapp' 為預設值
queryParam = input('myapp');
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=' + this.queryParam();
return;
}
event.preventDefault();
}
}
在 HTML 中使用:
<a href="https://angular.dev" appSafeLink queryParam="myapp-docs-link">Angular Documentation</a>
注意,queryParam
沒有使用方括號 []
,因為這裡傳遞的是一個固定的字串,而不是來自 component class 的動態表達式。
使用別名簡化 HTML
可以為 input 定義別名,以簡化在 HTML 中的使用方式:
queryParam = input('myapp', { alias: 'appSafeLink' });
HTML 使用變得更簡潔:
<a href="https://angular.dev" appSafeLink="myapp-docs-link">Angular Documentation</a>
這樣,指令選擇器本身也能接收參數值,不需要額外的屬性。
使用依賴注入
指令可以利用 Angular 的依賴注入系統來訪問 host 元素和其他服務。
注入宿主元素
使用 inject()
函數可以直接獲取指令所附加的 DOM 元素:
import { Directive, ElementRef, inject, input } from '@angular/core';
@Directive({
selector: 'a[appSafeLink]',
standalone: true,
host: {
'(click)': 'onConfirmLeavePage($event)',
},
})
export class SafeLinkDirective {
queryParam = input('myapp', { alias: 'appSafeLink' });
// 注入 hostElementRef
private hostElementRef = inject<ElementRef<HTMLAnchorElement>>(ElementRef);
onConfirmLeavePage(event: MouseEvent) {
const wantsToLeave = window.confirm('Do you want to leave this app?');
if (wantsToLeave) {
// 使用 hostElementRef 直接訪問和修改 DOM
const address = this.hostElementRef.nativeElement.href;
this.hostElementRef.nativeElement.href =
address + '?from=' + this.queryParam();
return;
}
event.preventDefault();
}
}
使用 ElementRef
的好處:
不需要類型轉換,因為我們在注入時已經指定了元素類型
直接訪問真實的 DOM 元素
程式碼更加簡潔和類型安全
其他可注入服務
除了 ElementRef
,指令還可以注入其他 Angular 服務:
ChangeDetectorRef
:管理變更檢測...
Last updated