多选虚拟化
MultiSelect组件可以虚拟化其下拉列表中的元素,这样您就可以使用巨大的数据源,而不会出现UI性能问题。
启用UI虚拟化特性可以使组件在滚动时重用下拉列表中的一组项,而不是呈现整个数据源。它既可以处理视图模型已经拥有的本地数据,也可以在用户每次滚动组件提供的事件时获取远程数据。
本文简介
在MultiSelect中显示,滚动和过滤超过10k条记录,没有延迟和性能问题。
基础知识
本节将解释与虚拟化特性相关的参数和行为,以便您进行设置。
若要启用UI虚拟化,需要设置组件的以下参数:
ScrollMode
-Telerik.Blazor.DropDownScrollMode
-设置为DropDownScrollMode。虚拟
.它默认为“常规”滚动。高度
-字符串
-设置高度在嵌套中弹出设置组件的标签。它必须不是一个空/空
字符串。ItemHeight
-小数
-设置它的高度,每个单独的项目将在下拉菜单中。确保您的项目将有内容和任何项目模板。页大小
-int
-定义实际渲染和重用的物品数量。该值决定在每个滚动中加载多少项。项目数量必须足够大,根据ItemHeight
并弹出高度
,这样项目就比下拉菜单项多,这样就有了一个滚动条。
你可以找到一个基本的例子本地数据下面的部分。
为了与远程数据,你还需要:
ValueMapper
-< TValue Func <列表>、任务<列表< TItem > > >
组件将调用此方法来请求匹配的模型价值
它已经凝固了。这是必需的,因为对于远程数据价值
可能不在组件所拥有的初始数据集合中,否则就没有办法提取DataTextField
从它来渲染它。通常,在初始呈现时调用此方法仅用于获取当前选择的数据项。OnRead
-EventCallback
当用户滚动到相应的偏移量(跳过
),页大小
以及任何过滤器。这使您可以优化数据查询,并在需要时只返回当前需要的内容。设置arg游戏。数据
而且arg游戏。总计
事件参数对象的属性。
限制
- 当最初选择的项/项在与第一个不同的页面上时,打开下拉列表将不会滚动到所选的项。
本地数据示例
选择项的数量:@SelectedValues?。Count
@code { List SelectedValues { get; set; } List Data { get; set; } protected override void OnInitialized() { Data = Enumerable.Range(1, 12345).Select(x => new Person { Id = x, Name = $"Name {x}" }).ToList(); base.OnInitialized(); } public class Person { public int Id { get; set; } public string Name { get; set; } } }
远程数据示例
这个例子展示了以下的示例实现:
- 返回数据的异步远程服务。它是由本例的静态类模拟的,您可以根据需要进行重构,并且可以在中找到通过连线序列化它的示例这个示例项目的集合对于网格组件,方法是相同的。
一个
OnRead
调用该服务的事件处理程序。一个
ValueMapper
这也调用了服务。
运行这个程序,看看如何在MultiSelect中显示、滚动和过滤超过10k条记录,而不会出现来自远程端点的延迟和性能问题。为了演示,这些行动被人为地推迟了。
@using Telerik。数据Source @using Telerik.DataSource.Extensions Number of selected items: @SelectedValues?.Count
@code{ List SelectedValues { get; set; } = new List { 4, 1234 }; // pre-select an item to showcase the value mapper async Task GetRemoteData(MultiSelectReadEventArgs args) { DataEnvelope result = await MyService.GetItems(args.Request); args.Data = result.Data; args.Total = result.Total; } async Task> GetModelFromValue(List selectedValues) { // return a model that matches the selected value so the component can get its text return await MyService.GetItemsFromValue(selectedValues); } // mimics a real service in terms of API appearance, refactor as necessary for your app public static class MyService { static List AllData { get; set; } public static async Task> GetItems(DataSourceRequest request) { if (AllData == null) { AllData = Enumerable.Range(1, 12345).Select(x => new Person { Id = x, Name = $"Name {x}" }).ToList(); } await Task.Delay(400); // simulate real network and database delays. Remove in a real app var result = await AllData.ToDataSourceResultAsync(request); DataEnvelope dataToReturn = new DataEnvelope { Data = result.Data.Cast().ToList(), Total = result.Total }; return await Task.FromResult(dataToReturn); } public static async Task> GetItemsFromValue(List selectedValues) { await Task.Delay(400); // simulate real network and database delays. Remove in a real app return await Task.FromResult(AllData.Where(x => selectedValues.Contains(x.Id)).ToList()); } } // used to showcase how you could simplify the return of more than one value from the service public class DataEnvelope { public int Total { get; set; } public List Data { get; set; } } public class Person { public int Id { get; set; } public string Name { get; set; } } }