我的 ngrx 状态包含一系列项目:
export interface MyState {
myItems: ItemType[];
}
我有一个包含 ngFor 和异步管道的组件。
标记:
<app-my-item-details-card *ngFor="let myItem of myItems$ | async"> </app-my-item-details-card>
选择器:
this.myItems$ = createSelector(getMyState, state => state.myItems);
在AppMyItemDetailsCardComponent内部,我有一个布尔标志 displayDetails:boolean 和按钮 button(click)=“ displayDetails =!displayDetails” ,用于切换布尔标志。在详细信息面板上,我有一些输入,显示来自 MyItem 实例的一些数据,这些数据已传递到组件。用户可以修改这些html元素,然后单击保存按钮,该按钮将触发操作 MyItemUpdateAction 。在商店减速器中,我这样做:
const myItemToModifyIndex = state.myItems.findIndex(...predicated based on the passed a ction...)
// cloning the item that I need to modify.
const myItemClone = [...state.myItems[myItemToModifyIndex]];
// modifying properties on the cloned item using data from the action
myItemClone.interestingProperty = action.newValueFromUser;
// cloning the array of items from the state.
const myItemsArrayClone = [...state.myItems];
// setting new item in the cloned array.
myItemsArrayClone[myItemToModifyIndex] = myItemClone;
// return of new state.
return { myItems: myItemsArrayClone }
问题:
因为您可以从化简器中看到,我已经修改了状态,并且实质上创建了 myItems 数组的新实例以及我修改过的项目的副本 Angular < / strong> 异步管道会对存储中的更改做出反应,并重新提供我的组件列表。本身会重新呈现 AppMyItemDetailsCardComponent 的所有实例,并使显示组件详细信息的标志为false,并且UI更改和详细信息面板被隐藏。
问题:
1)这种模式是否有意义并适合NGRX的工作方式? (我是Redux中的新手)。
2)我可以通过在商店内保留显示详细信息面板的标志来解决此问题。基本上,而不是切换 button(click)=“ displayDetails =!displayDetails” 一个布尔标志,我将分派一个操作,该操作将更改MyItem本身实例上的标志,从而驱动详细信息的显示面板。可以认为这是一个好的解决方案吗?
答案 0 :(得分:2)
redux,ngrx和状态处理都是关于引用的。
如果创建一个新的数组引用,angular会认为这是一个新列表并重新提供所有内容。
但是,如果您改为更改数组中特定项目的引用,则angular只会推送新的[item] =“ myItem”并导致更新我的单个应用项目卡。
要非常仔细地创建新的状态树,只更新必要的内容。
我还将displayDetails放在该项目中,这样当您克隆状态更改且不会被覆盖时,它将保持同步。