Как предотвратить повторную инициализацию динамически генерируемых компонентов при добавлении нового объекта

#javascript #angular #typescript

#javascript #angular #typescript

Вопрос:

Часть моего приложения состоит из динамически генерируемых компонентов, которые создаются внутри цикла * ngFor следующим образом:

 <div *ngFor="let actionCategory of actionCategories | keyvalue">
    <h2>{{actionCategory.key}}</h2>
    <div *ngFor="let action of actionCategory.value | keyvalue">
        <app-gearset [action]="action"></app-gearset>
    </div>
    <button mat-button (click)="addComponent(actionCategory)">Add another set</button>
</div>
  

Пользователь также имеет возможность добавить больше этих компонентов, нажав кнопку, привязанную к addComponent() функции, которая выглядит следующим образом:

   addGearSetComponent(actionCategory) {
    this.actionCategories[actionCategory.key][Object.keys(this.actionCategories[actionCategory.key]).length] = {};
  }
  

Это добавляет новый пустой объект в конец actionCategory объекта, добавляя новый компонент в соответствующую часть приложения. Проблема в том, что состояние компонентов, которые уже присутствовали, сбрасывается каждый раз при добавлении нового.

Есть ли какой-либо способ сохранить состояние предыдущих компонентов в объекте без изменений при изменении объекта, к которому они привязаны? Есть ли лучший способ динамически генерировать компоненты на основе сложного объекта?

Комментарии:

1. Привет! Добро пожаловать в Stack Overflow. «состояние компонентов, которые уже присутствовали, сбрасывается каждый раз при добавлении нового» — что вы подразумеваете под состоянием? Если состояние равно actionCategories , то его не следует сбрасывать (оно будет повторно отображаться на основе того же значения). Но если вы говорите о каком-то другом состоянии пользовательского интерфейса, которое не является частью модели, тогда вам может потребоваться сохранить и эти состояния либо в другом объекте, либо в качестве дополнительного свойства в вашей существующей модели.

2. Спасибо! Компоненты отслеживают свое собственное состояние перед отправкой его через службу на сервер, но если пользователь изменяет состояние компонентов, а затем добавляет новое с помощью кнопки выше, старые компоненты повторно отображаются, а их состояние уничтожается.

Ответ №1:

После еще нескольких часов поиска в документах я наткнулся на trackBy функциональность. [trackBy][1]

Похоже, что, передав trackBy следующую функцию, я могу изменить способ рендеринга компонентов DOM:

 trackAction(index, action) {
    return action ? action.key : undefined;
}
  

Я признаю, что не совсем понимаю, как именно это работает за кулисами, но это предотвращает уничтожение и повторное отображение компонентов, которые присутствовали на странице, при добавлении нового. Мне придется следить за проблемами с производительностью, но я верю, что пока это сработает! 🙂
[1]: https://blog.angular-university.io/angular-2-ngfor/

Комментарии:

1. Мой первоначальный вопрос включал точные примеры рассматриваемого кода, а также вопрос, касающийся объектов, повторно генерируемых в DOM и теряющих свое состояние.

2. Да, но если trackBy это решит вашу проблему, это звучит как другая проблема. trackBy нельзя полагаться на сохранение состояния, как вы предлагаете.

3. Однако trackBy может использоваться для предотвращения повторного отображения объекта в DOM при изменении базового объекта, к чему и относился мой вопрос.

4. Все, что я говорю, это то, что вы вешаете себя, если ваш родитель зависит от того, что его дочерние элементы никогда не будут повторно отображаться.