|
| 1 | +--- |
| 2 | +title: Debounce/Throttle grid data source operations |
| 3 | +description: how to debounce or throttle grid data source operations |
| 4 | +type: how-to |
| 5 | +page_title: Debounce/Throttle grid data source operations |
| 6 | +slug: grid-kb-throttle-operations |
| 7 | +position: |
| 8 | +tags: |
| 9 | +ticketid: 1451805 |
| 10 | +res_type: kb |
| 11 | +--- |
| 12 | + |
| 13 | +## Environment |
| 14 | +<table> |
| 15 | + <tbody> |
| 16 | + <tr> |
| 17 | + <td>Product</td> |
| 18 | + <td>Grid for Blazor</td> |
| 19 | + </tr> |
| 20 | + </tbody> |
| 21 | +</table> |
| 22 | + |
| 23 | + |
| 24 | +## Description |
| 25 | +I want to specify a debounce time for filtering. This way I can (for example) set the debounce time to 500(ms), and then only have the grid filter when the user stops typing. |
| 26 | + |
| 27 | +This can be useful for filtering with remote data when using the FilterRow mode - it invokes a filter on every keystroke. |
| 28 | + |
| 29 | +## Solution |
| 30 | +There are two solutions to this: |
| 31 | + |
| 32 | +* Use the [FilterMenu](https://demos.telerik.com/blazor-ui/grid/filter-menu) filtering mode because it fires filtering requests only when the user presses a button. |
| 33 | + |
| 34 | + * If you want to keep the UI simple (e.g., to simplify the service logic that you want to implement), the following article shows how to hide he extra filters in the filter menu: [Only one filter option in FilterMenu]({%slug grid-kb-only-one-filtermenu-option%}) |
| 35 | + |
| 36 | + * if you already have an OData service that handles filtering, you can use that with the filter menu: [Get Telerik Grid Data from an OData v4 Service](https://github.com/telerik/blazor-ui/tree/master/grid/odata) |
| 37 | + |
| 38 | +* Implement the desired throttling/debouncing in the [OnRead event](https://docs.telerik.com/blazor-ui/components/grid/manual-operations). Below is an example of this. |
| 39 | + |
| 40 | + |
| 41 | +>caption Throttle grid data source requests |
| 42 | +
|
| 43 | +````CSHTML |
| 44 | +@* This example throttles all events. You may want to add logic that checks how the data source request changed |
| 45 | +for example, whether the filters changed or something else, so you can throttle only filtering, for example *@ |
| 46 | +
|
| 47 | +@implements IDisposable |
| 48 | +
|
| 49 | +@using System.Threading |
| 50 | +@using Telerik.DataSource |
| 51 | +@using Telerik.DataSource.Extensions |
| 52 | +
|
| 53 | +<TelerikGrid Data=@GridData TotalCount=@Total |
| 54 | + Pageable=true PageSize=15 |
| 55 | + OnRead=@ReadItems FilterMode="@GridFilterMode.FilterRow"> |
| 56 | + <GridColumns> |
| 57 | + <GridColumn Field=@nameof(Employee.Id) Title="ID" /> |
| 58 | + <GridColumn Field=@nameof(Employee.Name) Title="Name" /> |
| 59 | + </GridColumns> |
| 60 | +</TelerikGrid> |
| 61 | +
|
| 62 | +@code { |
| 63 | + public List<Employee> GridData { get; set; } |
| 64 | + public int Total { get; set; } = 0; |
| 65 | +
|
| 66 | + DataSourceRequest lastRequest { get; set; } |
| 67 | + Timer ThrottleTimer { get; set; } |
| 68 | +
|
| 69 | + void InitializeTimer() |
| 70 | + { |
| 71 | + int throttleTime = 500; |
| 72 | +
|
| 73 | + ThrottleTimer = new System.Threading.Timer(async (obj) => |
| 74 | + { |
| 75 | + await InvokeAsync(RequestData); |
| 76 | + ThrottleTimer.Dispose(); |
| 77 | + }, |
| 78 | + null, throttleTime, System.Threading.Timeout.Infinite); |
| 79 | + } |
| 80 | +
|
| 81 | + protected async Task ReadItems(GridReadEventArgs args) |
| 82 | + { |
| 83 | + lastRequest = args.Request; |
| 84 | + ThrottleTimer?.Dispose(); |
| 85 | + InitializeTimer(); |
| 86 | + } |
| 87 | +
|
| 88 | + async Task RequestData() |
| 89 | + { |
| 90 | + DataEnvelope DataResult = await FetchPagedData(lastRequest); |
| 91 | +
|
| 92 | + GridData = DataResult.CurrentPageData; |
| 93 | + Total = DataResult.TotalItemCount; |
| 94 | +
|
| 95 | + StateHasChanged(); |
| 96 | + } |
| 97 | +
|
| 98 | + public void Dispose() |
| 99 | + { |
| 100 | + try |
| 101 | + { |
| 102 | + ThrottleTimer.Dispose(); |
| 103 | + } |
| 104 | + catch { } |
| 105 | + } |
| 106 | +
|
| 107 | + //sample paging and data request logic - this is just data generation from here on |
| 108 | +
|
| 109 | + public async Task<DataEnvelope> FetchPagedData(DataSourceRequest request) |
| 110 | + { |
| 111 | + List<Employee> fullList = new List<Employee>(); |
| 112 | +
|
| 113 | + int totalCount = 100; |
| 114 | + for (int i = 0; i < totalCount; i++) |
| 115 | + { |
| 116 | + fullList.Add(new Employee() |
| 117 | + { |
| 118 | + Id = i, |
| 119 | + Name = "Name " + i, |
| 120 | + }); |
| 121 | + } |
| 122 | +
|
| 123 | + DataEnvelope result = new DataEnvelope(); |
| 124 | +
|
| 125 | + var dataSourceResult = fullList.ToDataSourceResult(request); |
| 126 | + result.CurrentPageData = (dataSourceResult.Data as IEnumerable<Employee>).ToList(); |
| 127 | + result.TotalItemCount = dataSourceResult.Total; |
| 128 | +
|
| 129 | + return result; |
| 130 | + } |
| 131 | +
|
| 132 | + public class DataEnvelope |
| 133 | + { |
| 134 | + public List<Employee> CurrentPageData { get; set; } |
| 135 | + public int TotalItemCount { get; set; } |
| 136 | + } |
| 137 | +
|
| 138 | + public class Employee |
| 139 | + { |
| 140 | + public int Id { get; set; } |
| 141 | + public string Name { get; set; } |
| 142 | + } |
| 143 | +} |
| 144 | +```` |
| 145 | + |
0 commit comments