我有一个带有分页/全局搜索功能的 mud Blazor 网格。当我在本地测试它时,搜索功能按预期工作,即一旦用户输入内容,它就会过滤掉网格,而且看起来非常快。当我将其托管到开发/阶段服务器时会出现问题。用户输入有延迟。另外,如果输入速度很慢,它也能正常工作。例如,如果我尝试在搜索框中快速输入“test”,那么即使我仔细输入了所有字符,它总是会丢失 1 或 2 个字符并将其打印为“tst”。按退格键时指针会频繁闪烁。
我尝试清除缓存,但托管后仍然不起作用,而在我的本地环境中执行上述操作时没有出现此类问题。
我不明白我做错了什么以及为什么性能受到影响。 注意:我立即从数据库加载数据集(在 onInitialized() 内)
代码:
索引.剃刀
<MudTable Items="CustomersWithOrderInfo" ServerData="new Func<TableState, Task<TableData<Data.Models.CustomerOrderInfoDTO>>>(LoadCustomers)" FixedHeader="true" FixedFooter="true" Class="table table-hover" Style="box-shadow:none !important;" @ref="table" Height="530px">
<ToolBarContent>
<div class="input-group mb-3" style="width:35%;">
<input type="text" class="form-control" placeholder="Search" value="@searchString" @oninput="@FilterChanged">
<div class="input-group-append">
<span class="input-group-text bg-primary" id="basic-addon1"><i class="fa fa-search fa-lg fa-charade text-white" style="font-size:small;"></i></span>
</div>
</div>
<br />
</ToolBarContent>
<HeaderContent>
<MudTh Style="font-weight: bold;width:12%;">Customer Id</MudTh>
<MudTh Style="font-weight: bold;width:13%">Customer Name</MudTh>
....
<MudTh Style="font-weight: bold;width:8%;">Actions</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Customer Id">@context.CustomerId</MudTd>
<MudTd DataLabel="Customer Name">@context.CustomerName</MudTd>
....
<MudTd DataLabel="Active">@context.IsActive</MudTd>
<MudTd DataLabel="">
...
</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="pageSizes" />
</PagerContent>
</MudTable>
索引库.cs
protected void FilterChanged(ChangeEventArgs args)
{
searchString = args.Value.ToString();
table.ReloadServerData();
}
protected async Task<TableData<CustomerOrderInfoDTO>> LoadCustomers(TableState tableState)
{
IEnumerable<CustomerOrderInfoDTO> data = CustomersWithOrderInfo.OrderByDescending(q => q.CustomerId);
data = data.Where(p =>
{
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (!string.IsNullOrEmpty(p.CustomerName) && p.CustomerName.Contains(searchString, StringComparison.OrdinalIgnoreCase))
return true;
if ($"{p.CustomerId}".Contains(searchString))
return true;
return false;
}).ToArray();
totalItems = data.Count();
pagedData = data.Skip(tableState.Page * tableState.PageSize).Take(tableState.PageSize).ToArray();
return new TableData<CustomerOrderInfoDTO>() { TotalItems = totalItems, Items = pagedData };
}
我认为这是因为你使用了
@oninput="@FilterChanged"
,这意味着每次你输入一个字符都会执行FilterChanged
。由于 FilterChanged
是一个需要一些时间的函数,这会在执行时给 UI 带来一些滞后。
尝试将
@oninput="@FilterChanged"
替换为 @onchange="@FilterChanged"
。当元素失去焦点时,这将执行 FilterChanged
。
另一种可能性是添加一个按钮或在按下
Enter
键时执行。
请参阅文档。
我在 Ant Blazor 上遇到了完全相同的问题。如果打字速度慢的话还可以,但是如果我打字速度很快,字符就会开始丢失。解决方法非常简单:将 DebounceMilliseconds="1000" 添加到您的输入组件中。
例如
解释其工作原理(归功于https://github.com/ant-design-blazor/ant-design-blazor/issues/1283#issuecomment-810108270):
由于输入的工作方式,字符串与 输入表单从字符串更新到文本框。
在 Blazor 服务器场景中,延迟是一个问题(想象一下 200 毫秒 对于平均请求),如果您向服务器发送多个更新, 他们会回复您状态,但您已经输入了更多内容。
解决此问题的一种方法是将去抖时间设置为 1 或 2+ 秒
- 这样,在互联网速度较慢的情况下,打字时不会发送任何请求。
如果您使用回车键或按钮来提交/搜索等 - 您可以 使用大得离谱的去抖时间,因为 onblur 事件会导致 更新(想想跳出,点击其他地方)。
您需要一个去抖间隔。在 MudBlazor 中,您可以利用 MudTextField 中的
DebounceInterval
属性来帮助您 - 这将防止您的过滤器在用户每次输入或删除字符时发出服务器请求。目前如果没有这个间隔,每次输入更改时您都会重新加载数据集。去抖将为用户提供一段时间来完成输入,然后处理数据集重新加载。