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

问题描述 投票:0回答:1

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

  • 如何使用
    ServerData
    属性?
  • 如何处理行点击?
  • 如何在 API 调用中发送附加过滤器/搜索条件?
  • 如何预设
    Page
    对象的
    PageSize
    GridState
blazor mudblazor pagedlist
1个回答
3
投票

假设您想要创建一个 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; }
}

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

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

如您所见,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;
}

您需要创建执行 API 调用的

GetAnimalList()
方法,因此您可以在其中执行数据库查询并返回
AnimalListDto
结果,其中填充了
Items
ItemTotalCount
属性。

完成后,恭喜!您已在 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 title="Edit" @onclick:stopPropagation @onclick="() => EditItem(context.Item!)">Edit</button>
            </CellTemplate>
        </TemplateColumn>
     </Columns>
    <PagerContent>
        <MudDataGridPager T="AnimalListItemDto" />
    </PagerContent>
</MudDataGrid>

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

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

private void EditItem(AnimalListItemDto item)
{
    YourEditMethod(item);
}

如何在 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
}

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

<EditForm Model="_requestDto" OnValidSubmit="Search">
    <InputText placeholder="e.g. Animal Name" @bind-Value="_requestDto.SearchTerm" />
    <button type="submit">Search</button>
</EditForm>

现在我们添加

Search
方法:

private async Task Search()
{
    if (_dataGrid is not null)
    {
        await _dataGrid!.ReloadServerData();
    }
}

现在

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

如何预设
Page
对象的
PageSize
GridState

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

首先,需要将状态加载到请求DTO中。因此,您需要实现一个状态管理器,例如名为

GridDataRequestDto
AnimalListState
类型实例,您可以通过向
Program.cs
MyStateHelper 添加作用域
builder.Services
服务来将其注入到页面中。然后在你的 Blazor 页面代码中:

@inject IMyStateHelper MyStateHelper;

protected override async Task OnParametersSetAsync()
{
    _requestDto = MyStateHelper.AnimalListState;
}

这样,在渲染时间时请求 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);
    }
}

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

© www.soinside.com 2019 - 2024. All rights reserved.