Signal 與 Observable 的轉換
Angular 提供了兩個實用的函數來在 Signal 與 Observable 之間進行轉換,這些函數位於 @angular/core/rxjs-interop
套件中。
Signal 轉 Observable
toObservable()
接收一個 signal,並將其轉換為 Observable。
import { toObservable } from '@angular/core/rxjs-interop';
clickCount = signal(0);
clickCount$ = toObservable(this.clickCount);
const subscription = this.clickCount$.subscribe({
next: (val) => console.log(`Current click count: ${val}`),
});
// 記得在組件銷毀時取消訂閱
this.destroyRef.onDestroy(() => {
subscription.unsubscribe();
});
注意事項:
傳入的是 signal 本身,不要加括號執行它
這樣創建的 observable 會在 signal 值更新時發出新值
Observable 轉 Signal
toSignal()
接收一個 observable,並將其轉換為 Signal。
import { toSignal } from '@angular/core/rxjs-interop';
interval$ = interval(1000);
intervalSignal = toSignal(this.interval$);
轉換後的 intervalSignal 就可以像一般的 Signal 一樣使用:
在 effect 中被捕捉
用於 computed 計算
在模板中直接呼叫顯示
<p>
intervalSignal: {{ intervalSignal() }}
</p>
初始值處理: 由於 observable 可能沒有初始值,轉換出的 signal 一開始可能是 undefined。載入頁面時,需要等待 observable 第一次發出值才會顯示。
如果想要指定初始值,可以傳入第二個參數:
intervalSignal = toSignal(this.interval$, { initialValue: 0 });
自動清理: 使用 toSignal 轉換的 Observable,Angular 會自動處理訂閱的清理工作,不需要手動呼叫 unsubscribe()。
使用場景
這些轉換函數特別適合在以下情況使用:
與現有 RxJS 程式碼整合:在逐步導入 Signal 的專案中
混合使用兩種模式:同時利用 RxJS 的操作符和 Signal 的簡潔性
逐步遷移:將舊的基於 Observable 的程式碼遷移到新的 Signal 架構
效能考量
Signal 通常比 Observable 有更好的效能,特別是在變更偵測方面
在頻繁更新的 UI 元件中,考慮將關鍵的 Observable 轉換為 Signal
Last updated