Компоненты повторно визуализируются при изменении состояния, даже если фактические значения совпадают - PullRequest
0 голосов
/ 30 августа 2018

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, который будет управлять отображением панели сведений. , Можно ли считать это хорошим решением?

1 Ответ

0 голосов
/ 31 августа 2018

Извлечение, обработка ngrx и состояния - все о ссылках.

если вы создаете новую ссылку на массив, angular думает, что это новый список, и перерисовывает все.

Но если вместо этого вы измените ссылку на конкретный элемент в массиве, angular будет только выдвигать новый [item] = "myItem" и вызывать обновление одной карты элемента моего приложения.

Очень важно создать новое дерево состояний, обновив только то, что необходимо.

Я бы также добавил displayDetails в элемент, таким образом он будет синхронизироваться при клонировании изменений состояния и не будет перезаписан.

...