I'm gonna be very specific with my question, hoping for an equally specific answer.
I've combed online, and the Angular docs on the subject is as vague for real life cases as asking you to pick a needle from the ocean. Ooh Angular docs...
What I have done so far
<mat-paginator (page)="pageEvent = $event" #paginator [length]="pageLength" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions">
</mat-paginator>
And this in my component
pageLength: number;
pageSize: 5;
pageSizeOptions = [5, 10, 25, 100];
and then I update the pageLength
when the endpoint response is in like so:
loadRequests() {
this.busy = true;
this.request_service.get_requests()
.subscribe((res) => {
console.log(res);
this.requests = res['requests'];
this.pageLength = this.requests.length; // let's assume length = 1000
});
}
The above renders renders the UI for the pagination nicely in the browser
The endpoint being consumed via .get_requests()
, for the sake of simplicity, returns only 1000 fixed items.
Now, this is how I'm rendering my list at the moment:
<mat-card *ngFor="let request of requests">
<mat-card-title> {{ request.title }}</mat-card-title>
</mat-card>
So with the above preamble, what steps are my left to complete to get pagination to work with this condition in mind:
Let's assume you've loaded the response data (Array) in requests .
You can probably create a method that returns a set of data from the requests property using the splice method.
Therefore, on the API subscribe results, it can be handled like this for the first time load:
this.request_service.get_requests()
.subscribe((res) => {
this.pageLength = res['requests'].length;
this.splicedData = res['requests'].slice(((0 + 1) - 1) * this.pageSize).slice(0, this.pageSize);
});
where pageSize
, has been defined in earlier on to a default value.
Then, anytime the user changes the mat-paginator
component in the template, the pageChangeEvent
is run. Template looks like this:
<mat-paginator (page)="pageChangeEvent($event)" [length]="pageLength" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions">
</mat-paginator>
Then its corresponding component method is this.
pageChangeEvent(event) {
const offset = ((event.pageIndex + 1) - 1) * event.pageSize;
this.splicedData = this.requests.slice(offset).slice(0, event.pageSize);
}
Finally, your *ngFor
can use the splicedData
array to populate itself.
<mat-card *ngFor="let request of splicedData">
<mat-card-title> {{ request.title }}</mat-card-title>
</mat-card>
You could use the mat-table
, it integrates very well with the mat-paginator
. Hiding the header and changing the style to make it look the way you want.
The component :
displayedColumns: string[] = ['requests'];
dataSource: MatTableDataSource<{request: number}>;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor() {
this.dataSource = new MatTableDataSource(values);
}
ngOnInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
The template :
<table mat-table [dataSource]="dataSource" matSort>
<!-- Requests Column -->
<ng-container matColumnDef="requests">
<th mat-header-cell *matHeaderCellDef mat-sort-header/>
<td mat-cell *matCellDef="let row"> {{row.request.title}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"/>
<tr mat-row *matRowDef="let row; columns: displayedColumns;">
</tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"/>
I used GitHub API for this example, you need to wait for the event on the paginator and then do the HTTP call to fetch the data
<mat-paginator [length]="pagelength"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
[showFirstLastButtons]="true"
(page)="goToPage($event)">
</mat-paginator>
public goToPage(pageEvent:PageEvent){
// the pageIndex is 0 in Mat-paginator
this.pagelength = pageEvent.pageIndex+1;
this.pageSize = pageEvent.pageSize;
this.loadRequests(
this.pageLength,
this.pageSize,
);
}
private _loadRequests(
page: number,pageSize:number
) {
this.RequestService.getAllRequests(
page,pageSize
).subscribe((response) => {
this.requests = response.requests;
this.totalRequests = response.count;
}, (error) =>
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.