Observable 是惰性的;因此,除非被訂閱,否則它不會發出值。另一方面,訊號始終具有值,包括 toSignal
函數建立的訊號。雖然 toSignal
函數追蹤 Observable,但它仍然需要一個初始值,直到 Observable 發出第一個值。預設情況下,初始值 undefined
,但可以透過 ToSignalOptions
的initialValue
選項覆寫。
interface ToSignalOptions<T> {
initialValue?: unknown;
requireSync?: boolean | undefined;
injector?: Injector | undefined;
manualCleanup?: boolean | undefined;
rejectErrors?: boolean | undefined;
equal?: ValueEqualityFn<T> | undefined;
}
在這篇文章中,我示範了向 toSignal
函數提供自訂初始值的兩個範例。
clientX
和 clientY
的值。在 toSignal
函數中提供初始值時,程式碼可以避免未定義的錯誤或在範本中指定預設值。 這取決於開發人員的偏好,但我更喜歡使用 intialValue
選項從訊號類型中刪除 undefined
。
document$ = inject(DOCUMENT);
click$ = fromEvent(this.document$, 'click')
.pipe(shareReplay({ bufferSize: 1, refCount: true }));
secondsBeforeFirstClick$ = interval(1000)
.pipe(takeUntil(this.click$));
numSeconds$ = this.secondsBeforeFirstClick$.pipe(count());
當使用者按一下文件時,click$
Observable 會發出 MouseEvent。 secondsBeforeFirstClick$
Observable 每秒發出一個整數,在第一次點擊發生時取消訂閱。 numSeconds$
Observable 計算第一次點選發生前經過的秒數。
numSecondsUndfined = toSignal(this.numSeconds$)
numSeconds = toSignal(this.numSeconds$, { initialValue: 0 });
toSignal
函數建立numSecondsUndefined
和numSeconds
訊號。前者的類型是Signal<number|undefined>
,而後者的類型是Signal<number>
。如果沒有initialValue
選項,則numSecondsUndefined
訊號的初始值是undefined。numSeconds
訊號的初始值為零,因為 initialValue
的選項值為零。
<div class="region">
@let value = numSecondsUndfined() ?? 0;
<p>Undefined initial value. Number of seconds before click: {{ value }}</p>
</div>
<div class="region">
<p>Use initialValue option. Number of seconds before click: {{ numSeconds() }}</p>
</div>
HTML 範本在第一次點擊之前顯示相同的數值 (0)。但是,我聲明了一個 @let 變數來應用nullish coalescing (??) 運算符,以便在 numSecondsUndefined
訊號未定義時傳回 0。 相比之下,numSeconds
訊號傳回一個數字,程式碼稍微清晰一些。
mouseXY$ = this.click$.pipe(
filter((e) => e instanceof MouseEvent),
map((e) => e as MouseEvent),
map(({ clientX, clientY }) => ({ x: clientX, y: clientY }))
);
bufferClicks$ = this.mouseXY$.pipe(bufferCount(2));
strClicks$ = this.bufferClicks$.pipe(
map((results) => results.map(({ x, y }) => `(${x}, ${y})`))
);
strClicksUndefined = toSignal(this.strClicks$);
strClicks = toSignal(this.strClicks$, { initialValue: [] });
mouseXY$
Observable 會發出每次滑鼠點選的 clientX
和 clientY
值。 bufferClicks$
發出一個緩衝區,其中保存了前兩次滑鼠點擊。 strClicks$
Observable 發出 X 和 Y 值的字串陣列。 strClick
訊號最初值是一個 empty array。 strClickUndefined
訊號最初值是 undefined。
<div class="fib">
@let xyValues = strClicksUndefined() ?? [];
<p>Undefined initial value. Show the last 2 clicks: {{ xyValues.join(', ') }}</p>
<p>Show the last 2 clicks: {{ strClicks().join(', ') }}</p>
</div>
HTML範本在前兩次點擊之前顯示一個空白字串。但是,我聲明了一個 @let 變數來應用nullish coalescing (??) 運算符,以便在 strClicksUndefined
訊號是undefined時傳回空陣列。 strClickssignal
會跳過此檢查,因為它總是會傳回一個陣列。
initialValue
屬性來覆寫undefined的預設值。toSignal
函數的回傳類型為T | undefined
,如果沒有initialValue
屬性。toSignal
函數有第二個參數時,回傳類型是T。