组合框的虚拟化
ComboBox组件可以在其下拉菜单中虚拟化元素,这样您就可以使用庞大的数据源,而不会出现UI性能问题。
启用UI虚拟化特性可以使组件在滚动时重用下拉菜单中的一组项,而不是呈现出整个数据源。它既可以处理视图模型已经拥有的本地数据,也可以在用户每次滚动组件提供的事件时获取远程数据。
本文中
在组合框中显示,滚动和过滤超过10k条记录,没有延迟和性能问题
基础知识
本节将解释与虚拟化特性相关的参数和行为,以便您进行设置。
开启UI虚拟化功能,需要设置组件的以下参数:
ScrollMode
-Telerik.Blazor.DropDownScrollMode
-设置为DropDownScrollMode。虚拟
.它默认为“常规”滚动。高度
-字符串
-设置高度在嵌套中弹出设置组件标签。它必须不是一个空/空
字符串。ItemHeight
-小数
-将其设置为每个单独项目将在下拉菜单中的高度。确保适应你的项目将拥有的内容和任何项目模板。页大小
-int
-定义实际渲染和重用的物品数量。该值决定在每个滚动上加载多少项。项目的数量必须足够大,根据ItemHeight
并弹出高度
,这样会有比下拉菜单更多的项目,所以会有一个滚动条。
可以找到一个基本的例子本地数据下面的部分。
为了工作远程数据,你还需要:
ValueMapper
-Func < TValue、任务< TItem > >
-组件将调用此方法来请求匹配的模型价值
它已经凝固了。这是必需的,因为使用远程数据时价值
可能不在组件拥有的初始数据集合中,否则就无法提取DataTextField
从它到渲染它。通常,该方法将在初始呈现时调用,仅用于获取当前选择的数据项。OnRead
-EventCallback
当用户滚动对应的偏移量时,组件将调用此事件(跳过
),页大小
还有任何过滤器。这使您可以优化数据查询,并在需要时只返回当前需要的数据。设置arg游戏。数据
和arg游戏。总计
属性。
限制
- 当最初选择的项目/项目与第一个页面不同时,打开下拉列表将不会滚动列表到所选项目。
本地数据示例
@SelectedValue
@code {int SelectedValue {get;设置;} List Data {get;设置;OnInitialized() {Data = Enumerable。范围(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; } } }
远程数据示例
本例展示了以下示例的实现:
- 返回数据的异步远程服务。在本例中,它是由一个静态类模拟的,您可以根据需要进行重构,并且可以在web中找到序列化它的示例这个示例项目集合对于网格组件,方法是相同的。
一个
OnRead
调用该服务的事件处理程序。一个
ValueMapper
这也调用了服务。
运行这个程序,看看如何在不出现延迟和来自远程端点的性能问题的情况下显示、滚动和过滤组合框中的10k条记录。为了演示,这些操作有人为的延迟。
@using Telerik。数据Source @using Telerik.DataSource.Extensions @SelectedValue
@code{ int SelectedValue { get; set; } = 1234; // pre-select an item to showcase the value mapper async Task GetRemoteData(ComboBoxReadEventArgs args) { DataEnvelope result = await MyService.GetItems(args.Request); // set the Data and the TotalItems to the current page of data and total number of items args.Data = result.Data; args.Total = result.Total; } async Task GetModelFromValue(int selectedValue) { // return a model that matches the selected value so the component can get its text return await MyService.GetItemFromValue(selectedValue); } // 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 GetItemFromValue(int selectedValue) { await Task.Delay(400); // simulate real network and database delays. Remove in a real app return await Task.FromResult(AllData.FirstOrDefault(x => selectedValue == x.Id)); } } // 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; } } }