From Pluralsight/Building a Data-driven ASP.NET Core 6 Blazor Server Application with EF Core
Overview
Pagination allows you to limit the number of results you return per page and allows the user to request more results by specifying a page number.
Implement Pagination
Implementing pagination functionality involves:
- Counting the total number of records the Component has
- Specifying the number of records to show per page
- Using the above, counting the total number of pages (pages = records / recordsPerPage)
- Updating the logic to account for invalid page requests such as 0 or a number greater than the total number of pages
- Updating the page routes to include a pagination parameter
EmployeeOverview.razor
@* since int is nullable, if no currentPage parameter is specified, this directive will still route to this EmployeeOverview Component: *@
@page "/employees/list/{currentPage:int?}"
@inject IDbContextFactory<EmployeeManagerDbContext> ContextFactory;
@inject NavigationManager NavigationManager; @* NavigateTo() *@
<PageTitle>Employees</PageTitle>
<h1>Employees</h1>
<!-- ... -->
@code
{
private const int ItemsPerPage = 4;
// a property to hold the total number of pages:
private int TotalPages { get; set; }
private Employee[]? Employees { get; set; }
// this Parameter is populated from the route:
[Parameter]
public int? CurrentPage { get; set; }
protected override async Task OnParametersSetAsync()
{
// if this page was called without paging or with a page value that is <= 0, navigate to /employees/list/1:
if (CurrentPage is null or < 1)
{
NavigationManager.NavigateTo("/employees/list/1");
return;
}
using var context = ContextFactory.CreateDbContext();
// get the employee count
var employeeCount = await context.Employees.CountAsync();
// get the total number of pages we have by dividing the employee count with items per page:
// Math.Ceiling rounds up to the next whole integer
TotalPages = employeeCount == 0 ? 1 : (int)Math.Ceiling((double)employeeCount / ItemsPerPage);
// if the requested page is beyond the total number of pages we have, navigate to the last page that we have:
if (CurrentPage > TotalPages)
{
NavigationManager.NavigateTo($"/employees/list{TotalPages}");
return;
}
// if CurrentPage == 1, itemsToSkip == 0
// if CurrentPage == 2, itemsToSkip == 4
var itemsToSkip = (CurrentPage.Value - 1) * ItemsPerPage;
Employees = await context.Employees.Include(emp => emp.Department)
.OrderBy(emp => emp.FirstName)
.Skip(itemsToSkip) // skip items based on the CurrentPage parameter
.Take(ItemsPerPage) // always take n items
.ToArrayAsync();
}
}