Angular 在 v17.3 引入了改進的 outputs API,並自 v19 起視為已可正式使用。這個 API 仿效 input() API,但不是以訊號為基礎。
關於自訂事件的 output 函式及其優點,詳情請見專門的指南。
為了支援想使用 output 函式的既有專案,Angular 團隊提供了一項自動化遷移,能把 @Output 自訂事件轉換為新的 output() API。
使用以下指令執行此原理圖:
ng generate @angular/core:output-migration
遷移會更動什麼?
@Output()類別成員會更新為對應的output()形式。- 元件或指令所在檔案中,TypeScript 模組層級的 imports 也會一併更新。
- 把像
event.next()這類不建議使用的 API 呼叫遷移為event.emit(),並移除event.complete()呼叫。
遷移前
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
template: `<button (click)="someMethod('test')">emit</button>`,
})
export class MyComponent {
@Output() someChange = new EventEmitter<string>();
someMethod(value: string): void {
this.someChange.emit(value);
}
}
遷移後
import {Component, output} from '@angular/core';
@Component({
template: `<button (click)="someMethod('test')">emit</button>`,
})
export class MyComponent {
readonly someChange = output<string>();
someMethod(value: string): void {
this.someChange.emit(value);
}
}
設定選項
這項遷移支援幾個選項,可依你的具體需求微調遷移方式。
--path
如果沒有指定,遷移會向你詢問路徑,並更新你整個 Angular CLI 工作區。 你可以使用這個選項,把遷移限制在特定的子目錄。
--analysis-dir
在大型專案中,你可以使用這個選項來減少被分析的檔案數量。
依預設,無論 --path 選項為何,遷移都會分析整個工作區,以便更新所有受 @Output() 遷移影響的參照。
使用這個選項,可以把分析限制在某個子資料夾。請注意,這表示該目錄之外的任何參照都會被默默略過,可能會破壞你的建置。
如下所示使用這些選項:
ng generate @angular/core:output-migration --path src/app/sub-folder
例外情況
在某些情況下,遷移不會更動程式碼。
其中一個例外是:在測試檔案之外,事件搭配 pipe() 方法使用的情況。
以下程式碼不會被遷移:
export class MyDialogComponent {
@Output() close = new EventEmitter<void>();
doSome(): void {
this.close.complete();
}
otherThing(): void {
this.close.pipe();
}
}
在測試檔案中,遷移會改寫其用法,而不是略過該 output,因此 this.close.pipe(…) 會變成 outputToObservable(this.close).pipe(…)。
NOTE: 遷移判斷測試檔案的方式,是尋找路徑中含有 jasmine 或 catalyst 的 import。它無法辨識只匯入 Jest 或 Vitest 的檔案,因此在那種情況下會略過該 output,而不是改寫它。