@@ -60,8 +60,6 @@ public partial class Select<TValue> : ISelect, IModelEqualityComparer<TValue>
6060
6161 private readonly List < SelectedItem > _children = [ ] ;
6262
63- private readonly List < SelectedItem > _dataSource = [ ] ;
64-
6563 /// <summary>
6664 /// 获得/设置 右侧清除图标 默认 fa-solid fa-angle-up
6765 /// </summary>
@@ -73,7 +71,6 @@ public partial class Select<TValue> : ISelect, IModelEqualityComparer<TValue>
7371 /// 获得/设置 搜索文本发生变化时回调此方法
7472 /// </summary>
7573 [ Parameter ]
76- [ NotNull ]
7774 public Func < string , IEnumerable < SelectedItem > > ? OnSearchTextChanged { get ; set ; }
7875
7976 /// <summary>
@@ -213,6 +210,68 @@ public partial class Select<TValue> : ISelect, IModelEqualityComparer<TValue>
213210
214211 private bool _init = true ;
215212
213+ private List < SelectedItem > ? _itemsCache ;
214+
215+ private ItemsProviderResult < SelectedItem > _result ;
216+
217+ private List < SelectedItem > Rows
218+ {
219+ get
220+ {
221+ _itemsCache ??= string . IsNullOrEmpty ( SearchText ) ? GetRowsByItems ( ) : GetRowsBySearch ( ) ;
222+ return _itemsCache ;
223+ }
224+ }
225+
226+ private SelectedItem ? SelectedRow
227+ {
228+ get
229+ {
230+ SelectedItem ??= GetSelectedRow ( ) ;
231+ return SelectedItem ;
232+ }
233+ }
234+
235+ private SelectedItem ? GetSelectedRow ( )
236+ {
237+ var item = Rows . Find ( Match )
238+ ?? Rows . Find ( i => i . Active )
239+ ?? Rows . Where ( i => ! i . IsDisabled ) . FirstOrDefault ( )
240+ ?? GetVirtualizeItem ( ) ;
241+
242+ if ( item != null )
243+ {
244+ if ( _init && DisableItemChangedWhenFirstRender )
245+ {
246+
247+ }
248+ else
249+ {
250+ _ = SelectedItemChanged ( item ) ;
251+ _init = false ;
252+ }
253+ }
254+ return item ;
255+ }
256+
257+ private List < SelectedItem > GetRowsByItems ( )
258+ {
259+ var items = new List < SelectedItem > ( ) ;
260+ items . AddRange ( Items ) ;
261+ items . AddRange ( _children ) ;
262+ return items ;
263+ }
264+
265+ private List < SelectedItem > GetRowsBySearch ( )
266+ {
267+ var items = OnSearchTextChanged ? . Invoke ( SearchText ) ?? FilterBySearchText ( GetRowsByItems ( ) ) ;
268+ return items . ToList ( ) ;
269+ }
270+
271+ private IEnumerable < SelectedItem > FilterBySearchText ( IEnumerable < SelectedItem > source ) => string . IsNullOrEmpty ( SearchText )
272+ ? source
273+ : source . Where ( i => i . Text . Contains ( SearchText , StringComparison ) ) ;
274+
216275 /// <summary>
217276 /// <inheritdoc/>
218277 /// </summary>
@@ -221,7 +280,6 @@ protected override void OnParametersSet()
221280 base . OnParametersSet ( ) ;
222281
223282 Items ??= [ ] ;
224- OnSearchTextChanged ??= text => Items . Where ( i => i . Text . Contains ( text , StringComparison ) ) ;
225283 PlaceHolder ??= Localizer [ nameof ( PlaceHolder ) ] ;
226284 NoSearchDataText ??= Localizer [ nameof ( NoSearchDataText ) ] ;
227285 DropdownIcon ??= IconTheme . GetIconByKey ( ComponentIcons . SelectDropdownIcon ) ;
@@ -233,16 +291,17 @@ protected override void OnParametersSet()
233291 var item = NullableUnderlyingType == null ? "" : PlaceHolder ;
234292 Items = ValueType . ToSelectList ( string . IsNullOrEmpty ( item ) ? null : new SelectedItem ( "" , item ) ) ;
235293 }
294+
295+ _itemsCache = null ;
296+ SelectedItem = null ;
236297 }
237298
238299 /// <summary>
239300 /// 获得/设置 数据总条目
240301 /// </summary>
241302 private int TotalCount { get ; set ; }
242303
243- private IEnumerable < SelectedItem > ? VirtualItems { get ; set ; }
244-
245- private List < SelectedItem > GetVirtualItems ( ) => ( VirtualItems ?? Items ) . ToList ( ) ;
304+ private List < SelectedItem > GetVirtualItems ( ) => FilterBySearchText ( GetRowsByItems ( ) ) . ToList ( ) ;
246305
247306 /// <summary>
248307 /// 虚拟滚动数据加载回调方法
@@ -259,26 +318,23 @@ private async ValueTask<ItemsProviderResult<SelectedItem>> LoadItems(ItemsProvid
259318 var data = await OnQueryAsync ( new ( ) { StartIndex = request . StartIndex , Count = count , SearchText = SearchText } ) ;
260319
261320 TotalCount = data . TotalCount ;
262- VirtualItems = data . Items ?? [ ] ;
263- return new ItemsProviderResult < SelectedItem > ( VirtualItems , TotalCount ) ;
321+ var items = data . Items ?? [ ] ;
322+ _result = new ItemsProviderResult < SelectedItem > ( items , TotalCount ) ;
323+ return _result ;
264324
265325 int GetCountByTotal ( ) => TotalCount == 0 ? request . Count : Math . Min ( request . Count , TotalCount - request . StartIndex ) ;
266326 }
267327
268328 private async Task SearchTextChanged ( string val )
269329 {
270330 SearchText = val ;
271- if ( OnQueryAsync == null )
272- {
273- // 通过 Items 提供数据
274- VirtualItems = OnSearchTextChanged ( SearchText ) ;
275- }
276- else
331+ _itemsCache = null ;
332+
333+ if ( OnQueryAsync != null )
277334 {
278335 // 通过 ItemProvider 提供数据
279336 await VirtualizeElement . RefreshDataAsync ( ) ;
280337 }
281- StateHasChanged ( ) ;
282338 }
283339
284340 /// <summary>
@@ -295,7 +351,6 @@ protected override bool TryParseValueFromString(string value, [MaybeNullWhen(fal
295351 private bool TryParseSelectItem ( string value , [ MaybeNullWhen ( false ) ] out TValue result , out string ? validationErrorMessage )
296352 {
297353 SelectedItem = Items . FirstOrDefault ( i => i . Value == value )
298- ?? VirtualItems ? . FirstOrDefault ( i => i . Value == value )
299354 ?? GetVirtualizeItem ( ) ;
300355
301356 // support SelectedItem? type
@@ -313,51 +368,6 @@ private bool TryParseSelectItem(string value, [MaybeNullWhen(false)] out TValue
313368 : new SelectedItem ( CurrentValueAsString , DefaultVirtualizeItemText ?? CurrentValueAsString ) ;
314369 }
315370
316- private void ResetSelectedItem ( )
317- {
318- _dataSource . Clear ( ) ;
319-
320- if ( string . IsNullOrEmpty ( SearchText ) )
321- {
322- _dataSource . AddRange ( Items ) ;
323- _dataSource . AddRange ( _children ) ;
324-
325- if ( VirtualItems != null )
326- {
327- _dataSource . AddRange ( VirtualItems ) ;
328- }
329-
330- SelectedItem = _dataSource . Find ( Match )
331- ?? _dataSource . Find ( i => i . Active )
332- ?? _dataSource . Where ( i => ! i . IsDisabled ) . FirstOrDefault ( )
333- ?? GetVirtualizeItem ( ) ;
334-
335- if ( SelectedItem != null )
336- {
337- if ( _init && DisableItemChangedWhenFirstRender )
338- {
339-
340- }
341- else
342- {
343- _ = SelectedItemChanged ( SelectedItem ) ;
344- _init = false ;
345- }
346- }
347- }
348- else if ( IsVirtualize )
349- {
350- if ( Items . Any ( ) )
351- {
352- VirtualItems = OnSearchTextChanged ( SearchText ) ;
353- }
354- }
355- else
356- {
357- _dataSource . AddRange ( OnSearchTextChanged ( SearchText ) ) ;
358- }
359- }
360-
361371 /// <summary>
362372 /// <inheritdoc/>
363373 /// </summary>
@@ -374,12 +384,11 @@ private void ResetSelectedItem()
374384 [ JSInvokable ]
375385 public async Task ConfirmSelectedItem ( int index )
376386 {
377- var ds = string . IsNullOrEmpty ( SearchText )
378- ? _dataSource
379- : OnSearchTextChanged ( SearchText ) ;
380- var item = ds . ElementAt ( index ) ;
381- await OnClickItem ( item ) ;
382- StateHasChanged ( ) ;
387+ if ( index < Rows . Count )
388+ {
389+ await OnClickItem ( Rows [ index ] ) ;
390+ StateHasChanged ( ) ;
391+ }
383392 }
384393
385394 /// <summary>
@@ -483,24 +492,15 @@ private async Task OnClearValue()
483492 }
484493
485494 SelectedItem ? item ;
486- if ( IsVirtualize )
495+ if ( OnQueryAsync != null )
487496 {
488- if ( VirtualizeElement != null )
489- {
490- await VirtualizeElement . RefreshDataAsync ( ) ;
491- item = VirtualItems ! . FirstOrDefault ( ) ;
492- }
493- else
494- {
495- VirtualItems = Items ;
496- item = Items . FirstOrDefault ( ) ;
497- }
497+ await VirtualizeElement . RefreshDataAsync ( ) ;
498+ item = _result . Items . FirstOrDefault ( ) ;
498499 }
499500 else
500501 {
501502 item = Items . FirstOrDefault ( ) ;
502503 }
503-
504504 if ( item != null )
505505 {
506506 await SelectedItemChanged ( item ) ;
0 commit comments