回顧第10天,effect追蹤signal並在任何signal值更新時運行effect函數。當signal不是effect的依賴項時,它會呼叫未追蹤的函數以防止訊號讀取。我對效果的主要挑戰是識別不應被視為效果函數依賴項的訊號。 當我發現ngXtension庫中的explicitEffect函數時,追蹤signal值得到了極大的簡化。 當dependency array中的signal發生變化時,explicitEffect函數才運行effect函數。
今天,我想用explicitEffect重寫第10天的effect例子。
npm i ngxtension
import { explicitEffect } from 'ngxtension/explicit-effect';
// character.component.ts
effect((onCleanUp) => {
const sub = getPersonMovies(this.id(), this.injector)
.subscribe((result) => {
if (result) {
const [person, ...rest] = result;
this.person.set(person);
this.films.set(rest);
} else {
this.person.set(undefined);
this.films.set([]);
}
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
});
onCleanUp(() => sub.unsubscribe());
});
constructor() {
explicitEffect([this.id], ([id], onCleanUp) => {
const sub = getPersonMovies(id, this.injector)
.subscribe((result) => {
if (result) {
const [person, ...rest] = result;
this.person.set(person);
this.films.set(rest);
} else {
this.person.set(undefined);
this.films.set([]);
}
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
});
onCleanUp(() => sub.unsubscribe());
});
}
只有當dependency array的id signal發生變更時,explicitEffect才會運作。 explicitEffect的第二個參數是執行explicitEffect邏輯的函數。 onCleanUp是一個explicitEffect清理函數,它在銷毀effect之前取消subscription。
untracked(() => {
if (this.id() !== this.searchId()) {
this.searchId.set(this.id());
}
});
#logIDsEffect = effect(() => console.log('id ->', untracked(this.id), 'searchID ->', this.searchId()));
if (this.id() !== this.searchId()) {
this.searchId.set(this.id());
}
explicitEffect不會明確追蹤searchId signal,因此不需要呼叫untracked函數來執行外部程式碼。
#logIDsEffect = explicitEffect([this.searchId], ([searchId]) => console.log('id ->', this.id(), 'searchID ->', searchId),
{ defer: true });
我創建了一個新的explicitEffect來追蹤dependency array中的searchId signal。 explicitEffect函數記錄id和searchId的值。 新增第三個參數{ defer: rue }以延遲effect,直到searchId發生變更。
searchId = signal(initialId);
首次初始化searchId signal時沒有日誌訊息。
if (this.id() !== this.searchId()) {
this.searchId.set(this.id());
}
<input type="number" [(ngModel)]="searchId" name="searchId" id="searchId" />
當searchId signal變更時,將記錄該訊息。
this.renderer.setProperty(this.hostElement, 'style', `--main-font-size: ${untracked(this.fontSize)}`);
#rgbEffect = effect(() => console.log('rgb ->', this.rgb()));
this.renderer.setProperty(this.hostElement, 'style', `--main-font-size: ${this.fontSize()}`);
explicitEffect不會明確追蹤fontSize signal,因此,它不需要呼叫untracked函數來取得值。
#rgbEffect = explicitEffect([this.rgb], ([rgb]) => console.log('rgb ->', rgb), { defer: true });
我創建了一個新的explicitEffect來追蹤dependency array的rgb signal。 explicitEffect 函數記錄rgb值。 新增第三個參數{ defer: rue }以延遲effect,直到rgb發生變更。
rgb = signal('brown');
首次初始化rgb signal時沒有日誌訊息。
const sub = getPersonMovies(id, this.injector)
.subscribe((result) => {
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
});
設定rgb signal後,將記錄該訊息。
鐵人賽第11天就這樣結束了。