Skip to content

Commit daf5f10

Browse files
authored
feat(AutoFill): consistent with AutoComplete partial refresh of drop-down box (#5831)
* refactor: 增加防抖函数 * refactor: 增加双绑 * refactor: 增加双绑 * test: 更新单元测试 * test: 更新单元测试 * chore: bump version 9.5.7-beta01 * refactor: 重构代码 * refactor: 更新局部刷新逻辑
1 parent e9fc549 commit daf5f10

File tree

8 files changed

+40
-65
lines changed

8 files changed

+40
-65
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.5.6</Version>
4+
<Version>9.5.7-beta01</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,23 @@ export function init(id, invoke) {
6262
}
6363
});
6464

65-
Input.composition(input, async v => {
65+
let filterDuration = duration;
66+
if (filterDuration === 0) {
67+
filterDuration = 200;
68+
}
69+
const filterCallback = debounce(async v => {
70+
await invoke.invokeMethodAsync('TriggerFilter', v);
71+
el.classList.remove('is-loading');
72+
}, filterDuration);
73+
74+
Input.composition(input, v => {
6675
if (isPopover === false) {
6776
ac.show();
6877
}
6978

7079
el.classList.add('is-loading');
71-
await invoke.invokeMethodAsync('TriggerFilter', v);
72-
el.classList.remove('is-loading');
80+
filterCallback(v);
81+
7382
});
7483

7584
ac.show = () => {

src/BootstrapBlazor/Components/AutoFill/AutoFill.razor

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,22 @@
1414
data-bb-auto-dropdown-focus="@ShowDropdownListOnFocusString" data-bb-debounce="@DurationString"
1515
data-bb-skip-esc="@SkipEscString" data-bb-skip-enter="@SkipEnterString"
1616
data-bb-scroll-behavior="@ScrollIntoViewBehaviorString"
17-
value="@_displayText"
17+
@bind="@_displayText"
1818
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
1919
<span class="form-select-append"><i class="@Icon"></i></span>
2020
<span class="form-select-append ac-loading"><i class="@LoadingIcon"></i></span>
2121
@if (GetClearable())
2222
{
2323
<span class="@ClearClassString" @onclick="OnClearValue"><i class="@ClearIcon"></i></span>
2424
}
25-
<div class="dropdown-menu">
25+
<RenderTemplate @ref="_dropdown">
26+
@RenderDropdown
27+
</RenderTemplate>
28+
</div>
29+
30+
@code {
31+
RenderFragment RenderDropdown =>
32+
@<div class="dropdown-menu">
2633
@if (IsVirtualize)
2734
{
2835
<div class="dropdown-menu-body dropdown-virtual">
@@ -52,10 +59,8 @@
5259
}
5360
</div>
5461
}
55-
</div>
56-
</div>
62+
</div>;
5763

58-
@code {
5964
RenderFragment<TValue> RenderRow => item =>
6065
@<div @key="@item" class="dropdown-item" @onclick="() => OnClickItem(item)">
6166
@if (ItemTemplate != null)

src/BootstrapBlazor/Components/AutoFill/AutoFill.razor.cs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,10 @@ public partial class AutoFill<TValue>
149149
private List<TValue>? _filterItems;
150150

151151
[NotNull]
152-
private Virtualize<TValue>? _virtualizeElement = default;
152+
private Virtualize<TValue>? _virtualizeElement = null;
153+
154+
[NotNull]
155+
private RenderTemplate? _dropdown = null;
153156

154157
/// <summary>
155158
/// Gets the clear icon class string.
@@ -181,13 +184,6 @@ protected override void OnParametersSet()
181184
Items ??= [];
182185
}
183186

184-
private bool _render = true;
185-
186-
/// <summary>
187-
/// <inheritdoc/>
188-
/// </summary>
189-
/// <returns></returns>
190-
protected override bool ShouldRender() => _render;
191187

192188
private bool IsNullable() => !ValueType.IsValueType || NullableUnderlyingType != null;
193189

@@ -239,10 +235,7 @@ private async Task OnClickItem(TValue val)
239235

240236
private async ValueTask<ItemsProviderResult<TValue>> LoadItems(ItemsProviderRequest request)
241237
{
242-
_render = false;
243238
var data = await OnQueryAsync(new() { StartIndex = request.StartIndex, Count = request.Count, SearchText = _searchText });
244-
_render = true;
245-
246239
var _totalCount = data.TotalCount;
247240
var items = data.Items ?? [];
248241
return new ItemsProviderResult<TValue>(items, _totalCount);
@@ -261,7 +254,7 @@ public override async Task TriggerFilter(string val)
261254
{
262255
_searchText = val;
263256
await _virtualizeElement.RefreshDataAsync();
264-
StateHasChanged();
257+
_dropdown.Render();
265258
return;
266259
}
267260

@@ -276,29 +269,17 @@ public override async Task TriggerFilter(string val)
276269
}
277270
else
278271
{
279-
var comparision = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
272+
var comparison = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
280273
var items = IsLikeMatch
281-
? Items.Where(i => OnGetDisplayText?.Invoke(i)?.Contains(val, comparision) ?? false)
282-
: Items.Where(i => OnGetDisplayText?.Invoke(i)?.StartsWith(val, comparision) ?? false);
274+
? Items.Where(i => OnGetDisplayText?.Invoke(i)?.Contains(val, comparison) ?? false)
275+
: Items.Where(i => OnGetDisplayText?.Invoke(i)?.StartsWith(val, comparison) ?? false);
283276
_filterItems = [.. items];
284277
}
285278

286279
if (!IsVirtualize && DisplayCount != null)
287280
{
288281
_filterItems = [.. _filterItems.Take(DisplayCount.Value)];
289282
}
290-
StateHasChanged();
291-
}
292-
293-
/// <summary>
294-
/// Triggers the change method.
295-
/// </summary>
296-
/// <param name="val">The value to change to.</param>
297-
[JSInvokable]
298-
public Task TriggerChange(string val)
299-
{
300-
_displayText = val;
301-
StateHasChanged();
302-
return Task.CompletedTask;
283+
_dropdown.Render();
303284
}
304285
}

src/BootstrapBlazor/Components/Search/Search.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
data-bb-skip-esc="@SkipEscString" data-bb-skip-enter="@SkipEnterString" data-bb-blur="@TriggerBlurString"
3030
data-bb-scroll-behavior="@ScrollIntoViewBehaviorString"
3131
data-bb-input="@UseInputString"
32-
value="@_displayText"
32+
@bind="@_displayText"
3333
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
3434
@if (IsClearable)
3535
{

src/BootstrapBlazor/Components/Search/Search.razor.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public partial class Search<TValue>
172172
private SearchContext<TValue> _context = default!;
173173

174174
[NotNull]
175-
private RenderTemplate? _dropdown = default;
175+
private RenderTemplate? _dropdown = null;
176176

177177
/// <summary>
178178
/// <inheritdoc/>
@@ -282,14 +282,7 @@ private async Task OnClickItem(TValue val)
282282
/// </summary>
283283
/// <param name="val"></param>
284284
[JSInvokable]
285-
public override Task TriggerFilter(string val) => TriggerChange(val);
286-
287-
/// <summary>
288-
/// TriggerOnChange 方法
289-
/// </summary>
290-
/// <param name="val"></param>
291-
[JSInvokable]
292-
public async Task TriggerChange(string val)
285+
public override async Task TriggerFilter(string val)
293286
{
294287
_render = false;
295288
_displayText = val;

test/UnitTest/Components/AutoFillTest.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public async Task OnSelectedItemChanged_Ok()
164164
}
165165

166166
[Fact]
167-
public async Task OnGetDisplayText_Ok()
167+
public void OnGetDisplayText_Ok()
168168
{
169169
var cut = Context.RenderComponent<AutoFill<Foo>>(pb =>
170170
{
@@ -174,18 +174,6 @@ public async Task OnGetDisplayText_Ok()
174174
});
175175
var input = cut.Find("input");
176176
Assert.Equal("张三 1000", input.Attributes["value"]?.Value);
177-
178-
cut.SetParametersAndRender(pb =>
179-
{
180-
pb.Add(a => a.OnGetDisplayText, null!);
181-
});
182-
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
183-
184-
cut.SetParametersAndRender(pb =>
185-
{
186-
pb.Add(a => a.IsLikeMatch, true);
187-
});
188-
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
189177
}
190178

191179
[Fact]

test/UnitTest/Components/SearchTest.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ public async Task OnGetDisplayText_Ok()
5353
});
5454
pb.Add(a => a.OnGetDisplayText, foo => foo?.Name);
5555
});
56-
57-
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
58-
await Task.Delay(20);
59-
56+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
6057
Assert.Contains("test1", cut.Markup);
6158
Assert.Contains("test2", cut.Markup);
6259
}
@@ -143,7 +140,9 @@ public async Task OnSelectedItemChanged_Ok()
143140
return items;
144141
});
145142
});
146-
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
143+
144+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
145+
await Task.Delay(20);
147146

148147
var item = cut.Find(".dropdown-item");
149148
await cut.InvokeAsync(() => item.Click());

0 commit comments

Comments
 (0)