Reputation: 715
I want to let the user create a couple of selects, choose the options and agreggate these options in an array to be sent to a parent component.
I'm trying to do this with an *ngFor
that loops an array of strings (valueInputs
), creating a select for each element. An add button push a new empty string to valueInputs
, thus increasing the amount of selects. Finally, each select updates an index of valueInputs
via ngModel
.
Here's a Stackblitz to show it: https://stackblitz.com/edit/angular-q5nwjq
Component:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
valueInputs = ['', '', ''];
}
Template:
<ng-container *ngFor="let valueInput of valueInputs; let i = index">
<select
[(ngModel)]="valueInputs[i]">
<option value="" disabled>Select an option...</option>
<option value="opt1">Option 1</option>
<option value="opt2">Option 2</option>
</select>
</ng-container>
<div>
<button (click)="valueInputs.push('')">Add input</button>
<p>Value Inputs: {{ valueInputs | json }}</p>
</div>
Problem is: when I choose an option for the first select, the second select changes too! The actual value in the second valueInputs
index doesn't change, only the selected option.
This happens to all selects. You change one, the next changes too.
Does this make any sense? Or it's a bug in Angular? Do you have any suggestions to achieve the same results?
Upvotes: 0
Views: 2008
Reputation: 6152
I edited your stackblitz. To use ngFor with primitive data types you have to use "trackBy"
Two modifications:
trackByIdx(index: number, obj: any): any {
return index;
}
and in your html:
<ng-container *ngFor="let valueInput of valueInputs; let i = index; trackBy:trackByIdx">
Also check this answer for more details.
Upvotes: 2