Signal 的 set() 與 update() 用法差異

基本用法

set() 方法

當變數是 signal,可以透過 set() 來對於這個變數賦予新值:

onToggleDetails() {
  this.isDetailVisible.set(!this.isDetailVisible());
}

set() 直接接收新的值作為參數,適合用於簡單的賦值情況。

update() 方法

update() 是收一個函數作為參數,在函數內 Angular 會自動將舊的 signal 值作為參數傳遞給該函數:

onToggleDetails() {
  this.isDetailVisible.update((wasVisible) => !wasVisible);
}

update() 使用回調函數來計算新值,回調函數會接收目前的值作為參數。

進階用法

處理物件

當 signal 的值是物件時,兩種方法的差異更明顯:

// 使用 set() 要完全替換整個物件
this.user.set({ 
  ...this.user(), 
  name: 'Alice' 
});

// 使用 update() 可以更直觀地修改特定屬性
this.user.update(user => ({
  ...user,
  name: 'Alice'
}));

處理陣列

當 signal 的值是陣列時:

// 使用 set() 要完全替換整個陣列
this.items.set([...this.items(), newItem]);

// 使用 update() 可以更直覺地操作陣列
this.items.update(items => [...items, newItem]);

使用時機建議

  • 使用 set() 的情況

    • 當你已經有計算好的新值時

    • 當你要完全替換值時

    • 簡單布林值切換或單純賦值

  • 使用 update() 的情況

    • 當新值需要依賴舊值計算時

    • 處理複雜物件或陣列的部分更新

    • 需要在更新前進行額外邏輯判斷

效能考量

兩種方法在效能上沒有明顯差異,但 update() 在可讀性和維護性上可能對複雜操作更好,因為它清楚表明新值是從舊值計算得出的。

// 複雜計算的例子
this.cartTotal.update(total => {
  if (this.discountEligible()) {
    return total * 0.9; // 套用 10% 折扣
  }
  return total;
});

Last updated