You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:50:59