@@ -376,6 +376,7 @@ public partial class FluentDataGrid<TGridItem> : FluentComponentBase, IHandleEve
376376 // async query APIs that might be available. We have built-in support for using EF Core's async query APIs.
377377 private IAsyncQueryExecutor ? _asyncQueryExecutor ;
378378 private AsyncServiceScope ? _scope ;
379+ private bool _asyncQueryExecuted ;
379380
380381 // We cascade the InternalGridContext to descendants, which in turn call it to add themselves to _columns
381382 // This happens on every render so that the column list can be updated dynamically
@@ -411,6 +412,7 @@ public partial class FluentDataGrid<TGridItem> : FluentComponentBase, IHandleEve
411412 // things have changed, and to discard earlier load attempts that were superseded.
412413 private PaginationState ? _lastRefreshedPaginationState ;
413414 private IQueryable < TGridItem > ? _lastAssignedItems ;
415+ private bool ? _lastVirtualizationMode ;
414416
415417 private GridItemsProvider < TGridItem > ? _lastAssignedItemsProvider ;
416418 private CancellationTokenSource ? _pendingDataLoadCancellationTokenSource ;
@@ -483,12 +485,23 @@ protected override Task OnParametersSetAsync()
483485 _lastAssignedItemsProvider = ItemsProvider ;
484486 _lastAssignedItems = Items ;
485487 _asyncQueryExecutor = AsyncQueryExecutorSupplier . GetAsyncQueryExecutor ( _scope . Value . ServiceProvider , Items ) ;
488+ _asyncQueryExecuted = false ;
486489 }
487490
488491 var paginationStateHasChanged =
489492 Pagination ? . ItemsPerPage != _lastRefreshedPaginationState ? . ItemsPerPage
490493 || Pagination ? . CurrentPageIndex != _lastRefreshedPaginationState ? . CurrentPageIndex ;
491494
495+ if ( _lastVirtualizationMode != Virtualize )
496+ {
497+ _lastVirtualizationMode = Virtualize ;
498+ _asyncQueryExecuted = false ;
499+ }
500+ if ( Loading == true && _asyncQueryExecutor is not null && _asyncQueryExecuted )
501+ {
502+ Loading = false ; // switch to uncontrolled loading state after first IAsyncQueryExecutor completes
503+ }
504+
492505 var mustRefreshData = dataSourceHasChanged || paginationStateHasChanged || EffectiveLoadingValue ;
493506
494507 // We don't want to trigger the first data load until we've collected the initial set of columns,
@@ -865,7 +878,7 @@ private async Task RefreshDataCoreAsync()
865878 {
866879 Pagination ? . SetTotalItemCountAsync ( _internalGridContext . TotalItemCount ) ;
867880 }
868- if ( ( _internalGridContext . TotalItemCount > 0 && Loading is null ) || _lastError != null )
881+ if ( ( _internalGridContext . TotalItemCount > 0 && Loading != false ) || _lastError != null )
869882 {
870883 Loading = false ;
871884 StateHasChanged ( ) ;
@@ -904,13 +917,7 @@ private async ValueTask<GridItemsProviderResult<TGridItem>> ResolveItemsRequestA
904917 }
905918 else if ( Items is not null )
906919 {
907- if ( _asyncQueryExecutor is not null )
908- {
909- await OnItemsLoading . InvokeAsync ( true ) ;
910- }
911- var totalItemCount = _asyncQueryExecutor is null ? Items . Count ( ) : await _asyncQueryExecutor . CountAsync ( Items , request . CancellationToken ) ;
912- _internalGridContext . TotalItemCount = totalItemCount ;
913- IQueryable < TGridItem > ? result ;
920+ var result = Items ;
914921 if ( RefreshItems is null )
915922 {
916923 result = request . ApplySorting ( Items ) . Skip ( request . StartIndex ) ;
@@ -919,12 +926,24 @@ private async ValueTask<GridItemsProviderResult<TGridItem>> ResolveItemsRequestA
919926 result = result . Take ( request . Count . Value ) ;
920927 }
921928 }
929+ if ( _asyncQueryExecutor is not null )
930+ {
931+ await OnItemsLoading . InvokeAsync ( true ) ;
932+ var totalItemCount = await _asyncQueryExecutor . CountAsync ( Items , request . CancellationToken ) ;
933+ var resultArray = await _asyncQueryExecutor . ToArrayAsync ( result , request . CancellationToken ) ;
934+
935+ Loading = false ;
936+ _asyncQueryExecuted = true ;
937+ _internalGridContext . TotalItemCount = totalItemCount ;
938+
939+ return GridItemsProviderResult . From ( resultArray , totalItemCount ) ;
940+ }
922941 else
923942 {
924- result = Items ;
943+ var totalItemCount = Items . Count ( ) ;
944+ _internalGridContext . TotalItemCount = totalItemCount ;
945+ return GridItemsProviderResult . From ( [ .. result ] , totalItemCount ) ;
925946 }
926- var resultArray = _asyncQueryExecutor is null ? [ .. result ] : await _asyncQueryExecutor . ToArrayAsync ( result , request . CancellationToken ) ;
927- return GridItemsProviderResult . From ( resultArray , totalItemCount ) ;
928947 }
929948 }
930949 catch ( OperationCanceledException oce ) when ( oce . CancellationToken == request . CancellationToken )
@@ -939,11 +958,6 @@ private async ValueTask<GridItemsProviderResult<TGridItem>> ResolveItemsRequestA
939958 {
940959 if ( Items is not null && _asyncQueryExecutor is not null )
941960 {
942- if ( Loading == true )
943- {
944- Loading = false ;
945- StateHasChanged ( ) ;
946- }
947961 await OnItemsLoading . InvokeAsync ( false ) ;
948962 }
949963 }
0 commit comments