如何在Blazor客户端实现基于Skip/Top参数的分页功能
实现Blazor客户端分页功能
1. 先解决参数传递问题
你当前OnInitializedAsync里的API调用写法有误,多了冗余的括号,且需要定义分页参数变量来传递有效值。
首先在Index.razor的@code块中添加分页状态变量:
// 分页核心参数 private int currentPage = 1; // 当前页码(从1开始) private int pageSize = 10; // 每页显示的数据条数
然后修正API调用逻辑,根据当前页码计算skip值:
protected async override Task OnInitializedAsync() { // skip = (当前页-1) * 每页条数,用于告诉API跳过前面多少条数据 int skip = (currentPage - 1) * pageSize; // 直接传递计算后的skip和pageSize给API方法 pamilist = await ProductRepo.PatientsWithPagination(skip, pageSize); }
2. 完善完整分页逻辑
仅传递参数还不够,需要实现分页交互和状态管理,以下是完整步骤:
步骤1:扩展API返回数据(必须)
要实现完整分页,API需要返回总数据条数,这样才能计算总页数、禁用无效分页按钮。先创建一个分页结果DTO:
// 新建PaginationResult.cs public class PaginationResult<T> { public List<T> Items { get; set; } = new List<T>(); public int TotalCount { get; set; } // 总数据条数 }
修改HttpRepository的方法,适配新的返回类型:
public async Task<PaginationResult<Pami>> PatientsWithPagination(int skip, int top) { // 如果API是用QueryString接收参数,更推荐这种写法: // var url = $"patientinfo?skip={skip}&top={top}"; var url = Path.Combine("patientinfo", skip.ToString(), top.ToString()); var response = await _client.GetAsync(url); var content = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { throw new ApplicationException(content); } var result = JsonSerializer.Deserialize<PaginationResult<Pami>>(content, _options); return result; }
步骤2:更新Index.razor的变量和数据加载逻辑
// 替换原有变量 private List<Pami> pamilist = new List<Pami>(); private PaginationResult<Pami> paginationResult; private int totalItems = 0; private bool isLoading; // 加载状态标识 // 封装数据加载方法,避免重复代码 private async Task LoadPageData() { isLoading = true; try { int skip = (currentPage - 1) * pageSize; paginationResult = await ProductRepo.PatientsWithPagination(skip, pageSize); pamilist = paginationResult.Items; totalItems = paginationResult.TotalCount; } finally { isLoading = false; } } // 重写初始化方法 protected async override Task OnInitializedAsync() { await LoadPageData(); }
步骤3:添加分页UI控件
在表格下方添加分页交互按钮:
<!-- 加载状态提示 --> @if (isLoading) { <div class="text-center py-3">加载中...</div> } <!-- 表格 --> <table class="table"> <!-- 原有表格内容不变 --> </table> <!-- 分页控件 --> <div class="d-flex align-items-center justify-content-center mt-3"> <button class="btn btn-sm btn-outline-primary me-2" disabled="@(currentPage <= 1)" @onclick="PreviousPage">上一页</button> <span>第 @currentPage 页 / 共 @TotalPages 页</span> <button class="btn btn-sm btn-outline-primary ms-2" disabled="@(currentPage >= TotalPages)" @onclick="NextPage">下一页</button> <!-- 可选:页码跳转输入框 --> <input type="number" class="form-control form-control-sm w-auto ms-3" min="1" max="@TotalPages" value="@currentPage" @oninput="GoToSpecificPage" /> </div>
步骤4:添加分页交互方法
在@code块中补充分页操作逻辑:
// 计算总页数 private int TotalPages => (int)Math.Ceiling((double)totalItems / pageSize); // 上一页 private async Task PreviousPage() { if (currentPage > 1) { currentPage--; await LoadPageData(); } } // 下一页 private async Task NextPage() { if (currentPage < TotalPages) { currentPage++; await LoadPageData(); } } // 跳转到指定页码 private async Task GoToSpecificPage(ChangeEventArgs e) { if (int.TryParse(e.Value.ToString(), out int page) && page >= 1 && page <= TotalPages) { currentPage = page; await LoadPageData(); } }
3. 额外检查点
- 确认后端API路由和你HttpRepository中拼接的URL一致:如果API是通过路由参数接收
skip和top,那当前的Path.Combine写法没问题;如果是通过QueryString接收,建议改为var url = $"patientinfo?skip={skip}&top={top}"。 - 可以添加每页条数选择器,让用户自定义
pageSize,修改后重置currentPage为1并重新加载数据。
内容的提问来源于stack exchange,提问作者M Gopi
相关产品推荐
相关产品推荐

