Here's the html code:
<table class="table table-hover table-bordered table-striped table-highlight">
<thead>
<tr>
<th *ngFor="let cell of tableData2.headerRow">{{ cell }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tableData2.dataRows">
<td *ngFor="let cell of row">
<input type="text" class="form-control border-input" [(ngModel)]="cell" name="cell" />
</td>
</tr>
</tbody>
</table>
Here's the relevant typescript code:
declare interface TableData {
headerRow: string[];
dataRows: string[][];
}
public tableData2: TableData;
this.tableData2 = {
headerRow: ['Version', 'Approbateur(nom+fonction)', 'Principales remarques', 'Date d\'approbation'],
dataRows: [
['ahmed', '', '', ''],
['', '', '', ''],
['', '', '', ''],
['', '', '', ''],
['', '', '', ''],
['', '', '', ''],
['', '', '', ''],
]
};
As you may have noticed, the two-way data binding works in "one direction", the value "ahmed" does get displayed.
However, when I change the value of an input in a table like this:
And then I consoleLog the tableData2 variable:
As you may notice, the new value SAM doesn't get updated in the tabledata variable. I.e, the two-way data-binding doesn't work and I cannot retrieve the values from the table.
What did I do wrong?
2-way binding doesn't work on array value, it needs some object to update
So first change is let i = index;
and [(ngModel)]="row[i]"
:
<td *ngFor="let cell of row;
let i = index;
trackBy: customTrackBy
">
<input type="text" class="form-control border-input" [(ngModel)]="row[i]" name="cell" />
</td>
Second Change : (Issue is shown in demo)
// Your list will be reloaded again by ngFor when you change one field value,
// and it will lose the focus.
// You can add a trackBy to determine if the list must or must not be reloaded. The code below seems to solve the issue:
customTrackBy(index: number, obj: any): any {
return index;
}
WORKING DEMO ( With Solution + Issue )