使用 MudBlazor MudDataGrid ServerData 从 API 加载分页数据

Jam*_*ack 6 pagedlist blazor mudblazor

在我看来,当涉及到从 API 等动态源加载分页数据时,MudDataGrid 的文档有点缺乏。

  • 我该如何使用该ServerData属性?
  • 如何处理行点击?
  • 如何在 API 调用中发送附加过滤器/搜索条件?
  • 如何预设对象的Page和?PageSizeGridState

Jam*_*ack 19

假设您想要创建一个 blazor 页面,其中包含动物列表,并显示在 MudDataGrid 中。动物数据将来自 API。

我该如何使用该ServerData属性?

首先,定义 DTO 来处理用户的请求和 API 的响应:

public class GridDataRequestDto
{
    public int Page { get; set; } = 0; // The page number for the data we're requesting
    public int PageSize { get; set; } = 10; // The number of items per page
}

public class AnimalListDto
{
    public List<AnimalListItemDto> Items { get; set; } = new();
    public int ItemTotalCount { get; set; } = 0; // The total count of items before paging
}

public class AnimalListItemDto
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这就是 blazor 页面中 MudDataGrid 组件的实现:

<MudDataGrid ServerData="LoadGridData"
   T="AnimalListItemDto" @ref="_dataGrid">
    <Columns>
        <PropertyColumn Property="@(item => item.Name)" Title="Animal" />
     </Columns>
    <PagerContent>
        <MudDataGridPager T="AnimalListItemDto" />
    </PagerContent>
</MudDataGrid>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Grid 的ServerData属性设置为调用名为 的方法LoadGridData。我们在 blazor 页面代码中定义:

private MudDataGrid<AnimalListItemDto>? _dataGrid;
private GridDataRequestDto _requestDto = new();

private async Task<GridData<AnimalListItemDto>> LoadGridData(GridState<AnimalListItemDto> state)
{
    _requestDto.Page = state.Page;
    _requestDto.PageSize = state.PageSize;

    AnimalListDto apiResponse = await GetAnimalList(_requestDto);
    GridData<AnimalListItemDto> data = new()
        {
            Items = apiResponse.Items,
            TotalItems = apiResponse.ItemTotalCount
        };

    return data;
}
Run Code Online (Sandbox Code Playgroud)

您需要创建GetAnimalList()执行 API 调用的方法,因此您将在服务器上执行数据库查询并返回填充了和属性的AnimalListDto结果。ItemsItemTotalCount

完成后,恭喜你!您已在 MudDataGrid 中成功实施ServerData

如何处理行点击?

假设您希望用户在单击 MudDataGrid 行时查看动物。此外,您还想在每一行上放置一个按钮,以允许用户在单击该按钮时编辑动物。

我们稍微修改一下 blazor 页面代码中的 MudDataGrid 实现:

<MudDataGrid ServerData="LoadGridData" T="AnimalListItemDto" 
    RowClick="OnRowClick" Hover="true" @ref="_dataGrid">
    <Columns>
        <PropertyColumn Property="@(item => item.Name)" Title="Animal" />
        <TemplateColumn>
            <CellTemplate>
                <button @onclick="() => EditItem(context.Item!)" @onclick:stopPropagation>Edit</button>
            </CellTemplate>
        </TemplateColumn>
     </Columns>
    <PagerContent>
        <MudDataGridPager T="AnimalListItemDto" />
    </PagerContent>
</MudDataGrid>
Run Code Online (Sandbox Code Playgroud)

所以现在我们必须在代码中实现几个新方法:

private async Task OnRowClick(DataGridRowClickEventArgs<AnimalListItemDto> args)
{
    YourViewMethod(args.Item);
}

private void EditItem(AnimalListItemDto item)
{
    YourEditMethod(item);
}
Run Code Online (Sandbox Code Playgroud)

如何在 API 调用中发送附加过滤器/搜索条件?

现在我们希望用户能够通过在搜索框中输入关键字来搜索动物数据。

首先,我们需要将 SearchTerm 属性添加到我们的请求 DTO 中:

public class GridDataRequestDto
{
    public string? SearchTerm { get; set; } = null;
    public int Page { get; set; } = 0; // The page number for the data we're requesting
    public int PageSize { get; set; } = 10; // The number of items per page
}
Run Code Online (Sandbox Code Playgroud)

然后,我们将一个表单添加到 Blazor 页面的网格上方:

<EditForm Model="_requestDto" OnValidSubmit="Search">
    <InputText placeholder="e.g. Animal Name" @bind-Value="_requestDto.SearchTerm" />
    <button type="submit">Search</button>
</EditForm>
Run Code Online (Sandbox Code Playgroud)

现在我们添加Search方法:

private async Task Search()
{
    if (_dataGrid is not null)
    {
        await _dataGrid!.ReloadServerData();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在该SearchTerm属性自然会发送到 API 调用。您只需要修改数据库查询即可处理它。

如何预设对象的Page和?PageSizeGridState

这可能是一个利基要求,但您可能希望使用持久状态来预设数据网格以将不同的数据页面加载到默认值。如果用户离开页面然后返回,并期望数据位于他们离开的页面上,您可能需要执行此操作。

首先,您需要将状态加载到请求 DTO 中。因此,您需要实现一个状态管理器,例如,通过向Program.csGridDataRequestDto添加作用域服务来将AnimalListState其注入到页面中的类型实例。然后在您的 blazor 页面代码中:MyStateHelper builder.Services

@inject IMyStateHelper MyStateHelper;

protected override async Task OnParametersSetAsync()
{
    _requestDto = MyStateHelper.AnimalListState;
}
Run Code Online (Sandbox Code Playgroud)

这样,在渲染时间时请求 DTO 已被预先填充。所以最后一步是告诉 DataGrid 预先设置 Page 和 PageSize。MudBlazor 没有给我们一个很好的方法来做到这一点,但我发现这种方法有效:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender && _dataGrid?.HasPager == true)
    {
        _dataGrid!.CurrentPage = _requestDto.Page;
        await _dataGrid.SetRowsPerPageAsync(_requestDto.PageSize);
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是大家。如果您有任何问题,请告诉我。

  • 哇!很棒的答案! (3认同)