Exclore
Exclore

Reputation: 41

How to keep dynamically generated components from re-initializing when a new object is added

A portion of my app consists of dynamically generated components that are created inside a *ngFor loop like so:

<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>

The user also has the option of adding more of these components by clicking the button tied to the addComponent() function, which looks as follows:

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

This adds a new blank object to the end of the actionCategory object, adding a new component to the appropriate part of the app. The problem is that the state of the components that were already present is reset each time a new one is added.

Is there any way to keep the state of the previous components in the object intact when the object they are tied to is changed? Is there a better way to be dynamically generating components based on a complex object?

Upvotes: 1

Views: 63

Answers (1)

Exclore
Exclore

Reputation: 41

After a few more hours of hunting through docs I came across the trackBy functionality. [trackBy][1]

It looks like by handing trackBy the following function I'm able to alter the way the DOM re-renders components:

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

I'll admit I don't fully understand exactly how this works behind the scenes, but it's preventing components that were present on the page from being destroyed and re-rendered when a new one is added. I'll have to keep an eye out for performance issues, but I believe this will work for now! :) [1]: https://blog.angular-university.io/angular-2-ngfor/

Upvotes: 2

Related Questions