I've got that Angular Material Table :
<table mat-table [dataSource]="data" [trackBy]="trackBy">
<ng-container
[matColumnDef]="column.value"
*ngFor="let column of columns; let i = index"
>
<th mat-header-cell *matHeaderCellDef>{{ column.label }}</th>
<td mat-cell *matCellDef="let element">
<input
matInput
[value]="element[column.value].value"
type="text"
(input)="updatedFn($event.target.value)"
/>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr>
</table>
And this ts file :
@Component({
...
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StuffComponent implements OnInit, OnChanges {
@Input() data!: Data[];
@Input() columns!: Column[];
@Output() updated = new EventEmitter<Updated>();
columnsToDisplay!: string[];
constructor(private cdr: ChangeDetectorRef) {}
trackBy(index: number) {
return index;
}
ngOnChanges() {
this.cdr.markForCheck();
}
ngOnInit() {
this.columnsToDisplay = this._columns.map((item: Column) => item.value);
}
updatedFn(value: string) {
this.updated.emit(value);
}
}
I added the trackBy because I was losing focus on input whenever I'm typing. Now with trackBy, I can freely type, it dispatches the action, then I use the reducer to make the changes to the state, then it correctly send back the fresh data to the table component : the @Input() data/colums are corrects. However, it does not update the DOM. I assume this is because of the trackBy, but if I use something like this :
trackBy(index: number, stuff) {
return stuff.value;
}
...it loses focus again on the input.
Also, I tried to use this.cdr.markForCheck() but it did not do anything.
How can I update the DOM despite the trackyBy?
Edit: to be more precise on how I know it does not update the DOM -> in my reducer, I change the data value of another table cell but it does not appear on the table despite the @Input data contains the fresh data.
I found a solution: I added the same trackyBy to the ngFor itself :
<ng-container [matColumnDef]="column.value" *ngFor="let column of columns; let i = index; trackBy: trackBy"
I also removed the ngOnChanges and markForCheck()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With