Keywords: Angular Material | Paginator | Data Pagination | PageEvent | Server-Side Pagination
Abstract: This article provides an in-depth exploration of properly implementing the Material Design paginator component in Angular applications. Through detailed analysis of best practices, we demonstrate how to configure paginator properties, handle page events, implement server-side data fetching, and compare alternative client-side pagination approaches. The article includes complete code examples and step-by-step explanations to help developers master the full implementation workflow, with special focus on event binding, data update mechanisms, and solutions to common issues.
Basic Paginator Configuration and Property Binding
In Angular Material, the paginator component provides robust data pagination capabilities. First, import the necessary dependencies in your module:
import { MatPaginatorModule } from '@angular/material/paginator';Then configure the basic properties in your component template:
<mat-paginator [length]="totalRecords"
[pageSize]="pageSize"
[pageSizeOptions]="[5, 10, 25, 100]"
(page)="handlePageChange($event)">
</mat-paginator>Define these properties in the corresponding component class:
export class DataTableComponent implements OnInit {
totalRecords = 100;
pageSize = 10;
pageSizeOptions = [5, 10, 25, 100];
// Other properties and methods
}Page Event Handling and Data Updates
The core functionality of the paginator lies in handling page change events. When users switch pages or change page size, the page event is triggered, carrying a PageEvent object:
interface PageEvent {
pageIndex: number;
pageSize: number;
length: number;
previousPageIndex?: number;
}Define the event handling method in your component:
handlePageChange(event: PageEvent): void {
this.currentPage = event.pageIndex;
this.pageSize = event.pageSize;
this.loadData();
}Server-Side Data Fetching Implementation
For large datasets, server-side pagination is recommended. Call the service to fetch data within the event handling method:
loadData(): void {
const params = {
page: this.currentPage,
size: this.pageSize
};
this.dataService.fetchData(params).subscribe({
next: (response) => {
this.dataSource = response.data;
this.totalRecords = response.total;
},
error: (error) => {
console.error('Data loading failed:', error);
}
});
}Alternative Client-Side Pagination Approach
For smaller datasets, client-side pagination can be used. Display current page data by calculating slice indices:
updateDisplayedData(): void {
const startIndex = this.currentPage * this.pageSize;
const endIndex = startIndex + this.pageSize;
this.displayedData = this.allData.slice(startIndex, endIndex);
}Using Paginator Methods
Although the paginator provides methods like nextPage() and previousPage(), event handling is typically more straightforward in practical applications. These methods are mainly used for programmatic control:
@ViewChild(MatPaginator) paginator!: MatPaginator;
navigateToNextPage(): void {
if (this.paginator.hasNextPage()) {
this.paginator.nextPage();
}
}
navigateToPreviousPage(): void {
if (this.paginator.hasPreviousPage()) {
this.paginator.previousPage();
}
}Complete Implementation Example
Here's a complete example of data table integration with paginator:
@Component({
selector: 'app-data-table',
template: `
<table mat-table [dataSource]="displayedData">
<!-- Column definitions -->
</table>
<mat-paginator [length]="totalRecords"
[pageSize]="pageSize"
[pageSizeOptions]="[5, 10, 25]"
(page)="handlePageChange($event)">
</mat-paginator>
`
})
export class DataTableComponent implements OnInit {
displayedData: any[] = [];
totalRecords = 0;
pageSize = 10;
currentPage = 0;
ngOnInit(): void {
this.loadData();
}
handlePageChange(event: PageEvent): void {
this.currentPage = event.pageIndex;
this.pageSize = event.pageSize;
this.loadData();
}
private loadData(): void {
this.dataService.getPaginatedData({
page: this.currentPage,
size: this.pageSize
}).subscribe({
next: (response) => {
this.displayedData = response.data;
this.totalRecords = response.total;
},
error: (error) => console.error('Error:', error)
});
}
}Common Issues and Solutions
In actual development, you might encounter issues where the paginator doesn't update the view. Ensure that all relevant properties are correctly set after data updates. If using MatTableDataSource, make sure the paginator instance is properly bound:
this.dataSource = new MatTableDataSource(data);
this.dataSource.paginator = this.paginator;With the above implementation, you can build fully functional, user-friendly pagination features that handle both local and remote data effectively.