I try to develop dynamic table with Add/Remove element button.
Each row have 2 cells - 1 is selected cell (which could be disabled/enabled) and input field (maybe important to make that clear).
I do that with Array (which store my object), ngModel
and indexed ngFor
to iterate over it.
Have problem when I try to delete element, then for some reason after I'm trying to add element to the table not all the data binding (not in the right state nor shown in the input field) properly, even though all the data is stored well.
I use to think that there is a problem with the ngFor
index, maybe when I update the array the ngFor
not started from 0, so my ngModel
and my attributes refer to the last element (which is empty new object).
Thanks for helps, the relevant code attached.
addIncludeRule() {
this.campaign.includeRules.push({
"data": "",
"includeData": "",
"excludeData": "",
"type": ""
});
}
//==========================================================================
public removeIncludeRule(i: number) {
this.campaign.includeRules.splice(i, 1);
}
<tbody class="esf-table__body">
<tr class="esf-table__row" *ngFor="let irule of campaign.includeRules; index as i">
<td class="esf-table__cell">
<select [(ngModel)]="irule.type" name=iruleType{{i}} (change)="disabledOptionFlags(irule.type,0)" class="esf-form-item__field esf-select__field" [disabled]="irule.type[i]">
<option *ngFor="let ioption of options" value={{ioption.value}} [disabled]=ioption.incDisabled>{{(irule.data) ? irule.type : ioption.value}}</option>
</select>
</td>
<td class="esf-table__cell">
<input [(ngModel)]="irule.data" name=iruleValue{{i}} class="esf-form-item__field" type="text" value={{irule.data}} />
</td>
<td class="esf-table__cell esf-table__cell--shrink">
<span class="esf-table__cell-inner">
<div *ngIf="incRulesSize != i+1; else addIncButton">
<button class="esf-button esf-button--simple" mat-button (click)="removeIncludeRule(i)">
<svg class="esf-icon esf-button__icon" width="16" height="16">
<use xlink:href="#esf-icon-trash-16"></use>
</svg>
<span class="esf-button__icon-text"></span>
</button>
</div>
<ng-template #addIncButton>
<div class="esf-submit-row__item">
<button class="esf-button esf-button--standard esf-button--filled" (click)="addIncludeRule()" [disabled]="incRulesLimit">Add</button>
</div>
</ng-template>
</span>
</td>
</tr>
</tbody>
You need to use trackBy
to let angular know to track the index, so for your iteration, just add:
*ngFor="let irule of campaign.includeRules; index as i; trackBy: myTrackByFn"
and in component:
myTrackByFn(index) {
return index;
}