I'd like to frequently update my data table (Covalent td-data-table
with several ng-template
) with new data pulled from a JSON REST API. More rows than will fit on browser so user may need to scroll vertically. But when I update the data in the table it redraws completely i.e. the vertical scroll position resets to the top, tool tips flash, etc..
Hacks to e.g. save/restore the vertical scroll such as below kind of work but they create a lot of visual mess, especially in Firefox.
// save vertical scroll
this.scrollTop = this.tableElt.nativeElement.querySelector('.td-data-table-scrollable').scrollTop;
// update table data here
this.data = newData;
// restore vertical scroll
setImmediate(() => {
this.tableElt.nativeElement.querySelector('.td-data-table-scrollable').scrollTop = this.scrollTop;
}
});
How can I cleanly update the data in a table (or any component really) without hacking to reset scroll positions & putting up with a lot of flashing behaviour?
If there is no solution using the Covalent data table, is there another Angular 2+ control that handles this properly?
Animated screen capture of problem: Vertical scroll snaps back when data is updated. Vertical scroll should be maintained across data updates.
You could try using a trackBy function. This function will be used to determine what rows of your *ngFor
have changed to optimize redraws.
<tbody>
<tr td-data-table-row *ngFor="let row of basicData; trackBy: getRowId">
<td td-data-table-cell *ngFor="let column of columns" [numeric]="column.numeric">
{{column.format ? column.format(row[column.name]) : row[column.name]}}
</td>
<td td-data-table-cell (click)="openPrompt(row, 'comments')">
<button mat-button [class.mat-accent]="!row['comments']">{{row['comments'] || 'Add Comment'}}</button>
</td>
</tr>
</tbody>
And then in your Typescript:
getRowById(index, row) {
// Return some unique primitive idenitifier (string, number, etc.)
return row['some unique property'];
}
For more info on trackBy
check out:
https://netbasal.com/angular-2-improve-performance-with-trackby-cc147b5104e5 https://blog.angular-university.io/angular-2-ngfor/
Also, NGX-Datatable works very well for this use-case. It has built in virtual scrolling. https://github.com/swimlane/ngx-datatable