My ngrx state contains an array of items:
export interface MyState {
myItems: ItemType[];
}
I have a component that contains ngFor with an async pipe.
markup:
<app-my-item-details-card *ngFor="let myItem of myItems$ | async"> </app-my-item-details-card>
selector:
this.myItems$ = createSelector(getMyState, state => state.myItems);
Inside of the AppMyItemDetailsCardComponent I have a boolean flag displayDetails:boolean and button button (click)="displayDetails = !displayDetails" that toggles boolean flag. On the details panel I have some inputs that displays some data from MyItem instance that is passed to the component. User can modify those html elements and click Save button, that fires of an action MyItemUpdateAction. In the store reducer I do something like this:
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 }
Problem:
Because as you can see from the reducer that I have modified the state and essentially created a new instances of the myItems array and a copy of the item that I have modified, Angular async pipe reacts to the change in the store and re-renders my list of components. Which in itself re-renders all instances of AppMyItemDetailsCardComponent and it causes the flag that displays details of the component to false and UI changes and details panel is hidden.
Questions:
1) Does this pattern make sense and fits in with how things are done with NGRX? (I am new to redux in angular).
2) I can resolve this by keeping the flag that displays the details panel inside of the store. Basically instead of toggling button (click)="displayDetails = !displayDetails" a boolean flag, I would dispatch an action that would change a flag on an instance of MyItem itself that would drive the display of the details panel. Can this be considered a good solution?