My 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: логический и кнопка 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 async pipe реагирует на изменения в хранилище и повторно отображает мой список компонентов. Это само по себе повторно отображает все экземпляры AppMyItemDetailsCardComponent и приводит к тому, что флаг, отображающий сведения о компоненте, становится ложным, а изменения пользовательского интерфейса и панель сведений скрываются.
Вопросы:
1) Имеет ли этот шаблон смысл и соответствует ли это тому, как это делается с NGRX? (Я новичок в редуксе в угловой).
2) Я могу решить эту проблему, сохранив флаг, который отображает панель сведений внутри магазина. По сути, вместо переключения button (click) = "displayDetails =! DisplayDetails" логического флага, я бы отправил действие, которое изменит флаг на экземпляре самого MyItem, который будет управлять отображением панели сведений. , Можно ли считать это хорошим решением?