Search code examples
htmlangularngforangular-ngmodel

Entered text value is replicating in dynamic generated textbox through ngFor loop in angular 2


I have created a dynamic textbox using ngFor where number of textbox is generated by typing number in another textbox.

HTML.

    <div class="input-group col-sm-3">
        <span class="input-group-addon">Num of columns: </span>
        <input class="form-control"
               (change)="addColumnLength($event.target.value)"
               [(ngModel)]="workModel.columnLength"
               placeholder="Enter num of columns">
    </div>
</div>
<div class="column-content col-sm-3">
    <div class="input-group col-sm-12" *ngFor="let column of workModel.columnData; let i= index ">
        <span class="input-group-addon">Column {{i + 1}} </span>
        <input class="form-control"
               [value]="workModel.columnData[i]"
               (change)="assignColumnData($event.target.value, i)">
    </div>
</div>

And this is my .ts file.

 addColumnLength( length : number ) {
    this.workModel.columnData = [];
    for ( let i = 0; i < length; i++ ) {
        this.workModel.columnData[i] =  undefined;
    }
}

assignColumnData( length : number, index : number ) {
    this.workModel.columnData[ index ] = length;
}

Here I'm able to generate the number of textbox inserted. But when I enter value in anyone of the textbox it is replicated in all other textbox which is dynamically generated.

I tried also using ngModel as follows

  <div class="input-group" *ngFor="let column of workModel.columnData; let i= index ">
    <span class="input-group-addon">Column {{i}} </span>
    <input class="form-control"
          name="index_{{i}}"
           [(ngModel)]="workModel.columnData[i]">
   </div>

This is also causing the same. Is there anything missed here. Thanks in advance.

Update: When I decrement the length in the text box whole array is resetting as I have given this.workModel.columnData = []. How to not erase the data entered in textbox ?


Solution

  • This issue can be solved by using trackBy.

    <div class="column-content col-sm-3">
        <div class="input-group col-sm-12" *ngFor="let column of workModel.columnData; let i= index; trackBy:trackByFn ">
            <span class="input-group-addon">Column {{i + 1}} </span>
            <input class="form-control"
                   [value]="workModel.columnData[i]"
                   (change)="assignColumnData($event.target.value, i)">
        </div>
    </div>
    
    ...........
    
    trackByFn(index: any) {
      return index;
    }
    

    You can refer https://angular.io/api/common/NgForOf for more info