Blazor使用MudBlazor动态创建未知列数MudTable运行报错问题
解答
功能可行性
完全可以用MudBlazor实现你要的带排序、列顺序调整、筛选的动态表格,你现在的报错和实现问题,本质是没搞懂MudTable的渲染生命周期和模板的用法。
报错原因
你看到的空引用异常定位非常明确:
- 组件第一次渲染的时候,
ServerData的异步请求还没返回,rowTable.Items此时是null,你直接在HeaderContent里写rowTable.Items.ElementAt(0),必然触发空引用错误。 - 你写的
RowTemplate逻辑完全错误:RowTemplate是单条行数据的渲染模板,MudTable会自动遍历拿到的所有数据,逐行调用这个模板,根本不需要你自己写两层循环去遍历rowTable.Items,这么写不仅会重复渲染单元格,还会在数据未加载时触发空引用。
修正后的实现
不要从rowTable.Items里取列定义,单独维护一个动态列的集合,从首次请求返回的数据里初始化列,避免首次渲染的空值问题。
组件Razor代码
<MudTable ServerData="@GetEntityRowData" @ref="rowTable" Elevation="1" Hover Striped Loading="@_isLoading" Sortable="true" ColumnReordering="true"> <ToolBarContent> <MudTextField @bind-Value="_searchKeyword" Placeholder="输入关键词筛选" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" Immediate="true" OnKeyUp="@(async () => await rowTable.ReloadServerData())" /> </ToolBarContent> <HeaderContent> @foreach (var col in _dynamicColumns) { <MudTh SortLabel="@col.Key">@col.Key</MudTh> } </HeaderContent> <RowTemplate> @* context是MudTable自动注入的当前行数据实例,不需要自己遍历Items取值 *@ @foreach (var col in _dynamicColumns) { <MudTd>@context.SourceRowJsonProperties[col.Key]</MudTd> } </RowTemplate> <NoRecordsContent> <MudText>No rows found</MudText> </NoRecordsContent> <LoadingContent> <MudText>Loading...</MudText> </LoadingContent> <PagerContent> <MudTablePager /> </PagerContent> </MudTable>
C#逻辑代码
@code { private MudTable<EntityRowDto>? rowTable; private List<KeyValuePair<string, object>> _dynamicColumns = new(); private bool _isLoading; private string _searchKeyword = string.Empty; private async Task<TableData<EntityRowDto>> GetEntityRowData(TableState state) { _isLoading = true; try { // MudTable页码从0开始,直接+1就是接口需要的页码,不用单独判断0的情况 var pageNumber = state.Page + 1; var sortField = state.SortLabel; var sortDir = state.SortDirection == SortDirection.Ascending ? "asc" : "desc"; var url = $"api/entityrow?pageNumber={pageNumber}&pageSize={state.PageSize}&keyword={Uri.EscapeDataString(_searchKeyword)}&sortField={sortField}&sortDirection={sortDir}"; var response = await Http.GetFromJsonAsync<PagedResponse<EntityRowDto>>(url); // 第一次拿到数据时初始化动态列 if (response?.Items != null && response.Items.Any() && !_dynamicColumns.Any()) { _dynamicColumns = response.Items.First().SourceRowJsonProperties.ToList(); } return new TableData<EntityRowDto> { TotalItems = response?.Metadata.TotalItemCount ?? 0, Items = response?.Items ?? Enumerable.Empty<EntityRowDto>() }; } finally { _isLoading = false; } } }
MudTable数据访问说明
- 行渲染时直接用
RowTemplate里的context对象即可获取当前行数据,这是MudTable官方推荐的标准访问方式,不要通过@ref指向的表格实例去索引Items拿行数据。 - 如果需要在表格外部访问当前加载的分页数据,可以等
ServerData请求完成后再访问rowTable.Items,访问前一定要做判空处理,组件首次渲染阶段这个属性是null,不能直接调用Linq方法。 - 排序、列拖拽调整、筛选功能MudTable都已经内置,只需要开启对应参数,把
TableState里的分页、排序参数传给后端做对应的数据处理即可,不需要额外写前端交互逻辑。如果需要自定义筛选规则,在筛选输入变更后调用rowTable.ReloadServerData()就能触发表格重新请求数据。
内容的提问来源于stack exchange,提问作者Reggie
相关产品推荐
相关产品推荐

