Skip to content

Commit 7f1e7a5

Browse files
authored
Fix multiple requests for ItemsProvider when changing the TotalItemCount (#64661)
1 parent 6ca2f64 commit 7f1e7a5

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

src/Components/QuickGrid/Microsoft.AspNetCore.Components.QuickGrid/src/QuickGrid.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,6 @@ private async Task RefreshDataCoreAsync()
340340
else
341341
{
342342
// If we're not using Virtualize, we build and execute a request against the items provider directly
343-
_lastRefreshedPaginationStateHash = Pagination?.GetHashCode();
344343
var startIndex = Pagination is null ? 0 : (Pagination.CurrentPageIndex * Pagination.ItemsPerPage);
345344
var request = new GridItemsProviderRequest<TGridItem>(
346345
startIndex, Pagination?.ItemsPerPage, _sortByColumn, _sortByAscending, thisLoadCts.Token);
@@ -350,6 +349,7 @@ private async Task RefreshDataCoreAsync()
350349
_currentNonVirtualizedViewItems = result.Items;
351350
_ariaBodyRowCount = _currentNonVirtualizedViewItems.Count;
352351
Pagination?.SetTotalItemCountAsync(result.TotalItemCount);
352+
_lastRefreshedPaginationStateHash = Pagination?.GetHashCode();
353353
_pendingDataLoadCancellationTokenSource = null;
354354
}
355355
}

src/Components/test/E2ETest/Tests/QuickGridTest.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,36 @@ public void ItemsProviderCalledOnceWithVirtualize()
216216
Browser.Equal("1", () => app.FindElement(By.Id("items-provider-call-count")).Text);
217217
}
218218

219+
[Fact]
220+
public void FilterUsingSetCurrentPageDoesNotCauseExtraRefresh()
221+
{
222+
app = Browser.MountTestComponent<QuickGridFilterComponent>();
223+
224+
Browser.Equal("1", () => app.FindElement(By.Id("items-provider-calls")).Text);
225+
226+
var filterInput = app.FindElement(By.Id("filter-input"));
227+
filterInput.Clear();
228+
filterInput.SendKeys("Item 1");
229+
app.FindElement(By.Id("apply-filter-reset-pagination-btn")).Click();
230+
231+
Browser.Equal("2", () => app.FindElement(By.Id("items-provider-calls")).Text);
232+
}
233+
234+
[Fact]
235+
public void FilterUsingRefreshDataDoesNotCauseExtraRefresh()
236+
{
237+
app = Browser.MountTestComponent<QuickGridFilterComponent>();
238+
239+
Browser.Equal("1", () => app.FindElement(By.Id("items-provider-calls")).Text);
240+
241+
var filterInput = app.FindElement(By.Id("filter-input"));
242+
filterInput.Clear();
243+
filterInput.SendKeys("Item 1");
244+
app.FindElement(By.Id("apply-filter-refresh-data-btn")).Click();
245+
246+
Browser.Equal("2", () => app.FindElement(By.Id("items-provider-calls")).Text);
247+
}
248+
219249
[Fact]
220250
public void OnRowClickTriggersCallback()
221251
{

src/Components/test/testassets/BasicTestApp/Index.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<option value="@GetTestServerProjectComponent("Components.TestServer.ProtectedBrowserStorageInjectionComponent")">Protected browser storage injection</option>
9898
<option value="BasicTestApp.QuickGridTest.SampleQuickGridComponent">QuickGrid Example</option>
9999
<option value="BasicTestApp.QuickGridTest.QuickGridVirtualizeComponent">QuickGrid with Virtualize Example</option>
100+
<option value="BasicTestApp.QuickGridTest.QuickGridFilterComponent">QuickGrid Filter ItemsProvider Calls Test</option>
100101
<option value="BasicTestApp.RazorTemplates">Razor Templates</option>
101102
<option value="BasicTestApp.Reconnection.ReconnectionComponent">Reconnection server-side blazor</option>
102103
<option value="BasicTestApp.RedTextComponent">Red text</option>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
@using Microsoft.AspNetCore.Components.QuickGrid
2+
3+
<div>
4+
<input id="filter-input" type="text" @bind="filter" />
5+
<button id="apply-filter-reset-pagination-btn" @onclick="ApplyFilterResetPagination">Apply Filter</button>
6+
<button id="apply-filter-refresh-data-btn" @onclick="ApplyFilterRefreshData">Apply Filter</button>
7+
</div>
8+
9+
<div class="grid">
10+
<QuickGrid ItemsProvider="itemsProvider" Pagination="@pagination" @ref="gridRef">
11+
<PropertyColumn Property="@(c => c.Id)" />
12+
<PropertyColumn Property="@(c => c.Name)" />
13+
</QuickGrid>
14+
</div>
15+
<Paginator State="@pagination" />
16+
17+
<p id="items-provider-calls">@itemsProviderCalls</p>
18+
19+
@code {
20+
PaginationState pagination = new PaginationState { ItemsPerPage = 5 };
21+
int itemsProviderCalls = 0;
22+
GridItemsProvider<Item> itemsProvider = default!;
23+
QuickGrid<Item> gridRef;
24+
string filter = string.Empty;
25+
26+
private readonly List<Item> allItems = Enumerable.Range(1, 25)
27+
.Select(i => new Item { Id = i, Name = $"Item {i}" })
28+
.ToList();
29+
30+
protected override void OnInitialized()
31+
{
32+
itemsProvider = async request =>
33+
{
34+
await Task.CompletedTask;
35+
36+
Interlocked.Increment(ref itemsProviderCalls);
37+
StateHasChanged();
38+
39+
var filteredItems = string.IsNullOrEmpty(filter)
40+
? allItems
41+
: allItems.Where(i => i.Name.Contains(filter, StringComparison.OrdinalIgnoreCase)).ToList();
42+
43+
var totalCount = filteredItems.Count;
44+
var pagedItems = filteredItems
45+
.Skip(request.StartIndex)
46+
.Take(request.Count ?? 5)
47+
.ToList();
48+
49+
return GridItemsProviderResult.From(pagedItems, totalCount);
50+
};
51+
}
52+
53+
protected async Task ApplyFilterResetPagination()
54+
{
55+
await pagination.SetCurrentPageIndexAsync(0);
56+
}
57+
58+
protected async Task ApplyFilterRefreshData()
59+
{
60+
await gridRef.RefreshDataAsync();
61+
}
62+
63+
class Item
64+
{
65+
public int Id { get; set; }
66+
public string Name { get; set; } = string.Empty;
67+
}
68+
}

0 commit comments

Comments
 (0)