關於 @ngrx/Store 下 obj 的擴展問題

昨天做 task 的時候,遇到了一個問題。

TypeError: can't define property "x": "obj" is not extensible

而我的代碼是

 public txTiles: Array<TransactionFilterTile>;
 constructor(private _store: Store<AppStore>){
      _store.select(str => str.transactionState.tiles).subscribe(tiles => {
      this.txTiles = tiles;// tiles是一個對象數組
      this.txTiles.forEach( (x) => {
         x.currentStyle = { 'border-color': `${x.htmlColor}` };// 給currentStyle屬性再賦值
      });
   }
}

究其原因,項目中使用了 ngrx/store,它是 RXJS 的一種超牛叉的狀態管理,由 Redux 支持。Redux 可以確保 state 變化的可預測性,主要的約束有:

  • state 以單一對象存儲在 store 對象中;
  • state 只讀
  • 使用純函數 reducer 執行 state 更新

所以,服務器端的響應數據是隻讀的,且只能通過 dispatch(action)來觸發更新,所以在 ts 文件裏面不能隨意給 tile 的屬性重新賦值,可我又不想通過 dispatch 改變底層數據,那麼該怎麼辦呢? 我們可以克隆獲取的數據。修改後的代碼爲:

 _store.select(str => str.transactionState.tiles).subscribe(tiles => {
            this.txTiles = [];// 構建空數組
            if (tiles && tiles.length) {
                tiles.forEach(x => {
                    self.txTiles.push(new TransactionFilterTile(x));
                });
            }
           this.txTiles.forEach( (x) => {
              x.currentStyle = { 'border-color': `${x.htmlColor}` };// 給currentStyle屬性再賦值
      });
}

也就是構建空數組,然後把獲取到的數據放到空數組中,這樣既可以不更改底層數據,又可以在本組件中對從服務器獲取到的數據進行修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章