1

I have a parent component that generates some child components inside ngFor:

<app-test-child *ngFor="let size of model.sizes; let i = index" [model]="model" [lineNumber]="i">
</app-test-child>

The model contains an array of sizes:

export class TestModel {
  constructor(type: string) {
    this.type = type;
    this.sizes = new Array<number>();
  }

  type: string;
  sizes: Array<number>;
}

What I'm trying to do is get each child component to update one size in the model. The child component currently looks something like this:

Item {{lineNumber + 1}}: 
<select #radSize="ngModel" [(ngModel)]="model.sizes[lineNumber]">
  <option *ngFor="let size of availableItems" [ngValue]="size" [selected]="size === model.sizes[lineNumber]">{{size}}
  </option>
</select>
<br>

...where availableItems is a simple array of numbers.

Here's a demo of the code above.

Problem: If I select, say, the first item, the second item also updates and gets the focus. Actually, the ng-reflect-model value only updates for the first item, not the second, so it's just a visual issue, but very confusing for users.

Any ideas what's causing this to happen?

UPDATE

It seems that the real issue is due to the fact that ngModel is being bound to primitive values. According to this answer, that doesn't work very well.

The solution is to track the array by index. I've updated my demo, and it works perfectly!

Specifically, I added the following method to the parent component:

  trackByIdx(index: number, obj: any): any {
    return index;
  }

Then updated my template as follows:

<app-test-child *ngFor="let size of model.sizes; let i = index; trackBy:trackByIdx" [model]="model" [lineNumber]="i">
</app-test-child>
Michael McMullin
  • 1,450
  • 1
  • 14
  • 25

1 Answers1

1

Since the reference is passed to the child components caused the issue. Each child component should have a new instance of the test model to avoid the issue.

Still needs to investigate because it is not updating another child components. I observed like when I'm updating the first one then the third one's get updated.

Updating a parent model from different child components are needs to be synced up properly and there are many ways to acheive it instead of ngModel.

Here is the link, I updated the code and the second item is not getting updated when updating the first one. still few changes required at the model level. Ultimately the issue is due to pass by reference.

Editor URL - https://stackblitz.com/edit/angular-ivy-mecuia?file=src%2Fapp%2Ftest-parent.component.html