Blazor FluentDataGrid分页异常求助:总条数更新与页码错误
FluentDataGrid分页异常:总条目数不更新&切换页码始终为0
问题根源
- 异步方法错误导致状态丢失:
OnCurrentPageIndexChanged使用async void,Blazor无法正确跟踪这类异步方法的状态更新,引发页码重置等不可预测的异常。 - 重复设置分页状态:在分页事件中手动调用
SetCurrentPageIndexAsync,但FluentPaginator触发事件时已经自动更新了paginationState,重复操作会导致状态冲突。 - 页码索引不匹配:
PaginationState.CurrentPageIndex默认是0开始的索引,若你的API分页参数是1-based,直接传递会导致请求参数错误,进而引发分页异常。
修复步骤
1. 修正分页事件处理方法
把async void改为async Task,并移除手动设置页码的冗余代码:
async Task OnCurrentPageIndexChanged(int index) { await GetRoles(); }
2. 调整分页参数与总条目数设置
根据API的页码规则调整请求参数,确保获取数据后立即设置总条目数:
private async Task GetRoles() { gridLoader = true; StateHasChanged(); // 若API接受1-based页码,需给CurrentPageIndex加1;0-based则直接使用 request.Page = paginationState.CurrentPageIndex + 1; request.PageSize = paginationState.ItemsPerPage; var roleDataResponse = await httpClientService.GetAsync<Pagination.Response<IEnumerable<GetRoles.Response>>>("/api/roles", request); if (roleDataResponse != null) { RolesData = roleDataResponse; // 立即更新总条目数,让分页组件正确计算页数 await paginationState.SetTotalItemCountAsync(roleDataResponse.TotalRecords); } gridLoader = false; StateHasChanged(); }
3. 优化分页状态初始化
添加[SupplyParameterFromQuery]可以让分页状态持久化到URL,同时确保状态实例正确绑定:
[SupplyParameterFromQuery] private PaginationState paginationState = new PaginationState { ItemsPerPage = 10 };
4. 修正模板中的拼写错误
把模板里的@context.AssignedTo uers改为@context.AssignedTo users,避免前端显示错误。
完整修改后的关键代码
Razor组件部分
@rendermode InteractiveWebAssembly @inject HttpClientService httpClientService <FluentDataGrid Items="RolesData?.Data?.AsQueryable()" TGridItem="GetRoles.Response" Pagination="paginationState" ShowHover="true" MultiLine="true" Loading="@gridLoader"> <PropertyColumn Property="@(c => c.Name)" Sortable="false" /> <TemplateColumn Title="Permissions"> <p>@context.PermissionCount permissions assigned</p> </TemplateColumn> <TemplateColumn Title="Assigned To"> <p>@context.AssignedTo users</p> </TemplateColumn> <TemplateColumn Title="Actions"> @if (!context.IsPrimary) { <FluentButton aria-label="Edit item" IconEnd="@(new Icons.Regular.Size16.Edit())" OnClick="() => OnEditClick(context.Id)" /> <FluentButton aria-label="Delete item" IconEnd="@(new Icons.Regular.Size16.Delete())" OnClick="() => OnDeleteClick(context.Id)" /> } </TemplateColumn> </FluentDataGrid> <FluentPaginator State="@paginationState" CurrentPageIndexChanged="OnCurrentPageIndexChanged" />
逻辑代码部分
private GetRoles.Request request = new GetRoles.Request(); private Pagination.Response<IEnumerable<GetRoles.Response>>? RolesData; [SupplyParameterFromQuery] private PaginationState paginationState = new PaginationState { ItemsPerPage = 10 }; private bool gridLoader; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await GetRoles(); } } private async Task GetRoles() { gridLoader = true; StateHasChanged(); request.Page = paginationState.CurrentPageIndex + 1; request.PageSize = paginationState.ItemsPerPage; var roleDataResponse = await httpClientService.GetAsync<Pagination.Response<IEnumerable<GetRoles.Response>>>("/api/roles", request); if (roleDataResponse != null) { RolesData = roleDataResponse; await paginationState.SetTotalItemCountAsync(roleDataResponse.TotalRecords); } gridLoader = false; StateHasChanged(); } async Task OnCurrentPageIndexChanged(int index) { await GetRoles(); }
验证要点
- 检查API请求的
Page参数是否符合预期(比如第一页传1,第二页传2) - 查看控制台输出的
paginationState参数,确认TotalItemCount、CurrentPageIndex、LastPageIndex数值正确 - 切换分页时,确认API返回对应页码的数据,分页按钮状态正常
内容的提问来源于stack exchange,提问作者DrXSsive
相关产品推荐
相关产品推荐

