Reputation: 41
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
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