MatTableDataSource column header misalignment after dynamic page size change
0 reputation · 16 Mar 2020, 00:13 UTC
0 reputation · 16 Mar 2020, 00:13 UTC
When MatTableDataSource consumes server‑side data and the page size is changed programmatically, the column headers can shift out of alignment with their corresponding cells. The misalignment persists until a full table re‑render or browser resize forces a layout recalculation.
The issue appears when pageSize is updated on the paginator while the data source still holds the previous page’s row count. Internal header width calculations do not automatically reconcile with the new virtual scroll viewport dimensions.
Constraints include Angular Material 15–16 version differences in virtual scrolling implementation and the requirement to keep server‑side sorting and filtering active during the page size transition.
CdkVirtualScrollViewport directly instead of the built‑in paginator?31775 reputation · 16 Mar 2020, 03:14 UTC
Calling table.renderRows() after you change matPaginator.pageSize forces the MatTable to rebuild its rows and synchronises header widths, removing the misalignment.
The MatTable’s internal header width calculation runs only on the initial render and does not automatically recompute when the paginator’s pageSize changes, leaving header widths out of sync with the virtual‑scroll viewport after the row count changes.
matPaginator.pageSize while MatTableDataSource still holds the previous page’s row count causes header cells to shift relative to body cells until a layout trigger such as a window resize or full table re‑render occurs.table.renderRows() after the pageSize change forces the table to rebuild its row view and triggers header width synchronization, correcting the alignment without a full component reload.NgZone.run(() => {})) or call the private method table._updateColumnCssVar(), but the latter is not guaranteed across releases.page event (or detect when you programmatically set paginator.pageSize).paginator.pageSize, call this.table.renderRows() where table is the MatTable reference obtained via @ViewChild(MatTable).NgZone.run to guarantee change detection:import { AfterViewInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatTable } from '@angular/material/table';
import { NgZone } from '@angular/core';
export class MyComponent implements AfterViewInit {
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatTable) table!: MatTable;
constructor(private ngZone: NgZone) {}
ngAfterViewInit(): void {
this.paginator.page.subscribe(() => {
// pageSize may have changed via UI or programmatically
this.ngZone.run(() => {
this.table.renderRows();
});
});
}
// Example of programmatic change
changePageSize(newSize: number): void {
this.paginator.pageSize = newSize;
this.paginator._changePageSize(this.paginator); // paginator internal update
this.ngZone.run(() => this.table.renderRows());
}
}
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.