Skip to content

Files

Latest commit

May 19, 2022
12d604f · May 19, 2022

History

History
181 lines (132 loc) · 5.68 KB
·

virtualization.md

File metadata and controls

181 lines (132 loc) · 5.68 KB
·
title page_title description slug tags published position
Virtualization
MultiSelect - Virtualization
UI virtualization to allow large data sources in the MultiSelect for Blazor.
multiselect-virtualization
telerik,blazor,MultiSelect,virtualization
true
25

MultiSelect Virtualization

The MultiSelect @template

In This Article

caption Display, scroll and filter over 10k records in the MultiSelect without delays and performance issues.

Virtual Scrolling of large local data

Basics

@template

  • ValueMapper - Func<List<TValue>, Task<List<TItem>>> - @template

@template

Limitations

@template

Local Data Example

Number of selected items: @SelectedValues?.Count
<br />
<TelerikMultiSelect Data="@Data"

                    ScrollMode="@DropDownScrollMode.Virtual"
                    ItemHeight="30"
                    PageSize="20"

                    AutoClose="false"
                    TextField="@nameof(Person.Name)"
                    ValueField="@nameof(Person.Id)"
                    @bind-Value="@SelectedValues"
                    Filterable="true" FilterOperator="@StringFilterOperator.Contains">
    <MultiSelectSettings>
        <MultiSelectPopupSettings Height="200px" />
    </MultiSelectSettings>
</TelerikMultiSelect>

@code {
    List<int> SelectedValues { get; set; }
    List<Person> 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; }
    }
}

Remote Data Example

@template

@template

Run this and see how you can display, scroll and filter over 10k records in the MultiSelect without delays and performance issues from a remote endpoint. There is artificial delay in these operations for the sake of the demonstration.

@using Telerik.DataSource
@using Telerik.DataSource.Extensions

Number of selected items: @SelectedValues?.Count
<br />
<TelerikMultiSelect TItem="@Person" TValue="@int"
                    ScrollMode="@DropDownScrollMode.Virtual"
                    OnRead="@GetRemoteData"
                    ValueMapper="@GetModelFromValue"
                    ItemHeight="30"
                    
                    AutoClose="false"
                    PageSize="20"
                    TextField="@nameof(Person.Name)"
                    ValueField="@nameof(Person.Id)"
                    @bind-Value="@SelectedValues"
                    Filterable="true" FilterOperator="@StringFilterOperator.Contains">
    <MultiSelectSettings>
        <MultiSelectPopupSettings Height="200px" />
    </MultiSelectSettings>
</TelerikMultiSelect>

@code{
    List<int> SelectedValues { get; set; } = new List<int> { 4, 1234 }; // pre-select an item to showcase the value mapper

    async Task GetRemoteData(MultiSelectReadEventArgs args)
    {
        DataEnvelope<Person> result = await MyService.GetItems(args.Request);

        args.Data = result.Data;
        args.Total = result.Total;
    }

    async Task<List<Person>> GetModelFromValue(List<int> 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<Person> AllData { get; set; }

        public static async Task<DataEnvelope<Person>> 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<Person> dataToReturn = new DataEnvelope<Person>
            {
                Data = result.Data.Cast<Person>().ToList(),
                Total = result.Total
            };

            return await Task.FromResult(dataToReturn);
        }

        public static async Task<List<Person>> GetItemsFromValue(List<int> 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<T>
    {
        public int Total { get; set; }
        public List<T> Data { get; set; }
    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

See Also