Hello! In general, the
documentation of this component covers many issues of use, but in the process of actual development there are many pitfalls. I would like to talk about them and how I fought them.
Code readability
Example from documentation:
<mat-table #table [dataSource]="dataSource"> <ng-container matColumnDef="position"> ... </ng-container> <ng-container matColumnDef="weight"> ... </ng-container> ... </mat-table>
I will say this does not correspond to my concept of readability. And it will be absolutely terrible if there are more than 5 columns in the table. And here comes the ngFor (material data table add-on over the cdk data table, so dynamic columns are possible). Here's how it might look more readable:
')
<mat-table [dataSource]="data"> <ng-container *ngFor="let column of columns" [matColumnDef]="column.key"> <mat-header-cell *matHeaderCellDef>{{ column.header }}</mat-header-cell> <mat-cell *matCellDef="let row">{{ column.cell(row) }}</mat-cell> </ng-container> ... </mat-table>
columns = [ {key: 'position', header: 'Position', cell: (row: Row) => `${row.position}`}, {key: 'weight', header: 'Weight', cell: (row: Row) => `${row.weight}`}, ... ];
I also want to note that sorting does not work with an array field. So I had to hardcode with the addition of a number to the names of dynamic fields.
Sticky headers

.mat-header-row { position: sticky; top: 0; background: white; z-index: 9999; }
Such a simple solution, and your header line hangs when scrolling.
You can not be limited to it and make a static sidebar for convenience when scrolling horizontally data (example in the picture, how it works). It uses the [ngStyle] attribute for each dynamic cell (for the first two for each row with similar styles above).
Horizontal scrolling also breaks the separation of lines (and for the sticky parts, the background breaks off). The flex attribute here turned out to be a great helper.
Little about the filter
On the table page there is an important note about filtering by default:
For example, the data object {id: 123, name: 'Mr. Smith ', favoriteColor:' blue '} will be reduced to 123mr. smithblue
Personally, I think such an approach is hardly acceptable, as often when filtering there is visually confusion (no coincidence is observed). The most suitable option would be to filter separately for each visible field. Plus it is better not to introduce additional invisible fields with this approach (they will also bring their own confusion). But the developers have proposed a solution:
The filtering method can be set.
filterPredicate: ((data: T, filter: string) => boolean)
Problems solved. I advise you to override the default filtering.
Thanks to Angular developers for such a powerful framework and for your attention.
