Skip to content

Commit 8526429

Browse files
authored
feat(AufoFill): add TriggerFilter invoke method (#5191)
* refactor: 修复报错问题 * refactor: 减少私有变量 * wip: 临时提交 * Revert "refactor: 减少私有变量" This reverts commit 1da9709. * Revert "wip: 临时提交" This reverts commit 63d5bee. # Conflicts: # src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.cs * refactor: 精简代码逻辑 * test: 更新单元测试 * refactor: 更新内部逻辑 * test: 更新单元测试 * Revert "test: 更新单元测试" This reverts commit 38d331a. * test: 更新单元测试 * refactor: 重构代码 * refactor: 重构代码 * refactor: 重构代码 * test: 更新单元测试
1 parent 09e2ff3 commit 8526429

File tree

6 files changed

+100
-48
lines changed

6 files changed

+100
-48
lines changed

src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,7 @@ public partial class AutoComplete
8787
/// </summary>
8888
private string? ShowDropdownListOnFocusString => ShowDropdownListOnFocus ? "true" : null;
8989

90-
/// <summary>
91-
/// 获得/设置 UI 呈现数据集合
92-
/// </summary>
93-
[NotNull]
94-
private List<string>? FilterItems { get; set; }
90+
private List<string>? _filterItems;
9591

9692
/// <summary>
9793
/// <inheritdoc/>
@@ -110,10 +106,10 @@ protected override void OnParametersSet()
110106
{
111107
base.OnParametersSet();
112108

113-
LoadingIcon ??= IconTheme.GetIconByKey(ComponentIcons.LoadingIcon);
114109
NoDataTip ??= Localizer[nameof(NoDataTip)];
115110
PlaceHolder ??= Localizer[nameof(PlaceHolder)];
116111
Icon ??= IconTheme.GetIconByKey(ComponentIcons.AutoCompleteIcon);
112+
LoadingIcon ??= IconTheme.GetIconByKey(ComponentIcons.LoadingIcon);
117113

118114
Items ??= [];
119115
}
@@ -130,7 +126,7 @@ private async Task OnClickItem(string val)
130126
}
131127
}
132128

133-
private List<string> Rows => FilterItems ?? Items.ToList();
129+
private List<string> Rows => _filterItems ?? Items.ToList();
134130

135131
/// <summary>
136132
/// TriggerFilter 方法
@@ -142,24 +138,24 @@ public async Task TriggerFilter(string val)
142138
if (OnCustomFilter != null)
143139
{
144140
var items = await OnCustomFilter(val);
145-
FilterItems = items.ToList();
141+
_filterItems = items.ToList();
146142
}
147143
else if (string.IsNullOrEmpty(val))
148144
{
149-
FilterItems = Items.ToList();
145+
_filterItems = Items.ToList();
150146
}
151147
else
152148
{
153149
var comparison = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
154150
var items = IsLikeMatch
155151
? Items.Where(s => s.Contains(val, comparison))
156152
: Items.Where(s => s.StartsWith(val, comparison));
157-
FilterItems = items.ToList();
153+
_filterItems = items.ToList();
158154
}
159155

160156
if (DisplayCount != null)
161157
{
162-
FilterItems = FilterItems.Take(DisplayCount.Value).ToList();
158+
_filterItems = _filterItems.Take(DisplayCount.Value).ToList();
163159
}
164160
StateHasChanged();
165161
}

src/BootstrapBlazor/Components/AutoFill/AutoFill.razor

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<span class="form-select-append"><i class="@Icon"></i></span>
1919
<span class="form-select-append ac-loading"><i class="@LoadingIcon"></i></span>
2020
<ul class="dropdown-menu">
21-
@foreach (var item in FilterItems)
21+
@foreach (var item in Rows)
2222
{
2323
<li @key="@item" class="dropdown-item" @onclick="() => OnClickItem(item)">
2424
@if (ItemTemplate != null)
@@ -27,11 +27,11 @@
2727
}
2828
else
2929
{
30-
<div>@OnGetDisplayText(item)</div>
30+
<div>@GetDisplayText(item)</div>
3131
}
3232
</li>
3333
}
34-
@if (ShowNoDataTip && FilterItems.Count == 0)
34+
@if (ShowNoDataTip && Rows.Count == 0)
3535
{
3636
<li class="dropdown-item">@NoDataTip</li>
3737
}

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

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ public partial class AutoFill<TValue>
1919
.AddClassFromAttributes(AdditionalAttributes)
2020
.Build();
2121

22-
/// <summary>
23-
/// 获得 最终候选数据源
24-
/// </summary>
25-
[NotNull]
26-
private List<TValue>? FilterItems { get; set; }
22+
private List<TValue>? _filterItems;
2723

2824
/// <summary>
2925
/// 获得/设置 组件数据集合
@@ -119,10 +115,8 @@ protected override void OnParametersSet()
119115
Icon ??= IconTheme.GetIconByKey(ComponentIcons.AutoFillIcon);
120116
LoadingIcon ??= IconTheme.GetIconByKey(ComponentIcons.LoadingIcon);
121117

122-
OnGetDisplayText ??= v => v?.ToString();
123-
_displayText = Value is null ? "" : OnGetDisplayText(Value);
124-
125-
FilterItems ??= Items?.ToList() ?? [];
118+
_displayText = GetDisplayText(Value);
119+
Items ??= [];
126120
}
127121

128122
/// <summary>
@@ -131,40 +125,59 @@ protected override void OnParametersSet()
131125
private async Task OnClickItem(TValue val)
132126
{
133127
CurrentValue = val;
134-
_displayText = OnGetDisplayText(val);
128+
_displayText = GetDisplayText(val);
135129

136130
if (OnSelectedItemChanged != null)
137131
{
138132
await OnSelectedItemChanged(val);
139133
}
140134
}
141135

136+
private string? GetDisplayText(TValue item) => OnGetDisplayText?.Invoke(item) ?? item?.ToString();
137+
138+
private List<TValue> Rows => _filterItems ?? Items.ToList();
139+
142140
/// <summary>
143-
/// TriggerOnChange 方法
141+
/// TriggerFilter 方法
144142
/// </summary>
145143
/// <param name="val"></param>
146144
[JSInvokable]
147-
public async Task TriggerOnChange(string val)
145+
public async Task TriggerFilter(string val)
148146
{
149147
if (OnCustomFilter != null)
150148
{
151149
var items = await OnCustomFilter(val);
152-
FilterItems = items.ToList();
150+
_filterItems = items.ToList();
151+
}
152+
else if (string.IsNullOrEmpty(val))
153+
{
154+
_filterItems = Items.ToList();
153155
}
154156
else
155157
{
156-
var comparisionType = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
157-
FilterItems = IsLikeMatch
158-
? Items.Where(i => OnGetDisplayText(i)?.Contains(val, comparisionType) ?? false).ToList()
159-
: Items.Where(i => OnGetDisplayText(i)?.StartsWith(val, comparisionType) ?? false).ToList();
158+
var comparision = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
159+
var items = IsLikeMatch
160+
? Items.Where(i => OnGetDisplayText?.Invoke(i)?.Contains(val, comparision) ?? false)
161+
: Items.Where(i => OnGetDisplayText?.Invoke(i)?.StartsWith(val, comparision) ?? false);
162+
_filterItems = items.ToList();
160163
}
161164

162165
if (DisplayCount != null)
163166
{
164-
FilterItems = FilterItems.Take(DisplayCount.Value).ToList();
167+
_filterItems = _filterItems.Take(DisplayCount.Value).ToList();
165168
}
169+
StateHasChanged();
170+
}
166171

172+
/// <summary>
173+
/// TriggerOnChange 方法
174+
/// </summary>
175+
/// <param name="val"></param>
176+
[JSInvokable]
177+
public Task TriggerChange(string val)
178+
{
167179
_displayText = val;
168180
StateHasChanged();
181+
return Task.CompletedTask;
169182
}
170183
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ private async Task OnClickItem(TValue val)
200200
/// </summary>
201201
/// <param name="val"></param>
202202
[JSInvokable]
203-
public async Task TriggerOnChange(string val)
203+
public async Task TriggerChange(string val)
204204
{
205205
_displayText = val;
206206

test/UnitTest/Components/AutoFillTest.cs

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,17 @@ public async Task OnCustomFilter_Ok()
8484
return Task.FromResult(items.AsEnumerable());
8585
});
8686
});
87-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
87+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
8888
Assert.True(filtered);
89-
}
9089

90+
cut.SetParametersAndRender(pb =>
91+
{
92+
pb.Add(pb => pb.OnCustomFilter, null!);
93+
});
94+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter(""));
95+
var items = cut.FindAll(".dropdown-item");
96+
Assert.Equal(2, items.Count);
97+
}
9198

9299
[Fact]
93100
public void SkipEnter_Ok()
@@ -172,13 +179,13 @@ public async Task OnGetDisplayText_Ok()
172179
{
173180
pb.Add(a => a.OnGetDisplayText, null!);
174181
});
175-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
182+
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
176183

177184
cut.SetParametersAndRender(pb =>
178185
{
179186
pb.Add(a => a.IsLikeMatch, true);
180187
});
181-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
188+
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
182189
}
183190

184191
[Fact]
@@ -189,18 +196,18 @@ public async Task IgnoreCase_Ok()
189196
{
190197
builder.Add(a => a.Items, items);
191198
builder.Add(a => a.IgnoreCase, true);
192-
builder.Add(a => a.OnGetDisplayText, foo => foo.Name);
199+
builder.Add(a => a.OnGetDisplayText, foo => foo?.Name);
193200
});
194201

195-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
202+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
196203
var menus = cut.FindAll(".dropdown-item");
197204
Assert.Equal(4, menus.Count);
198205

199206
cut.SetParametersAndRender(pb =>
200207
{
201208
pb.Add(a => a.DisplayCount, 2);
202209
});
203-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
210+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
204211
menus = cut.FindAll(".dropdown-item");
205212
Assert.Equal(2, menus.Count);
206213

@@ -209,7 +216,7 @@ public async Task IgnoreCase_Ok()
209216
pb.Add(a => a.IgnoreCase, false);
210217
pb.Add(a => a.DisplayCount, null);
211218
});
212-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
219+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
213220
menus = cut.FindAll(".dropdown-item");
214221
Assert.Equal(2, menus.Count);
215222
}
@@ -222,18 +229,18 @@ public async Task IsLikeMatch_Ok()
222229
{
223230
builder.Add(a => a.Items, items);
224231
builder.Add(a => a.IsLikeMatch, false);
225-
builder.Add(a => a.OnGetDisplayText, foo => foo.Name);
232+
builder.Add(a => a.OnGetDisplayText, foo => foo?.Name);
226233
});
227234

228-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
235+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
229236
var menus = cut.FindAll(".dropdown-item");
230237
Assert.Equal(4, menus.Count);
231238

232239
cut.SetParametersAndRender(pb =>
233240
{
234241
pb.Add(a => a.DisplayCount, 2);
235242
});
236-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
243+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
237244
menus = cut.FindAll(".dropdown-item");
238245
Assert.Equal(2, menus.Count);
239246

@@ -242,9 +249,45 @@ public async Task IsLikeMatch_Ok()
242249
pb.Add(a => a.IsLikeMatch, true);
243250
pb.Add(a => a.DisplayCount, null);
244251
});
245-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("a"));
252+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("a"));
246253
menus = cut.FindAll(".dropdown-item");
247254
Assert.Equal(4, menus.Count);
255+
256+
cut.SetParametersAndRender(pb =>
257+
{
258+
pb.Add(a => a.OnGetDisplayText, null);
259+
pb.Add(a => a.IsLikeMatch, false);
260+
});
261+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
262+
menus = cut.FindAll(".dropdown-item");
263+
Assert.Single(menus);
264+
265+
cut.SetParametersAndRender(pb =>
266+
{
267+
pb.Add(a => a.OnGetDisplayText, null);
268+
pb.Add(a => a.IsLikeMatch, true);
269+
});
270+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
271+
menus = cut.FindAll(".dropdown-item");
272+
Assert.Single(menus);
273+
274+
cut.SetParametersAndRender(pb =>
275+
{
276+
pb.Add(a => a.OnGetDisplayText, foo => null);
277+
pb.Add(a => a.IsLikeMatch, false);
278+
});
279+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
280+
menus = cut.FindAll(".dropdown-item");
281+
Assert.Single(menus);
282+
283+
cut.SetParametersAndRender(pb =>
284+
{
285+
pb.Add(a => a.OnGetDisplayText, foo => null);
286+
pb.Add(a => a.IsLikeMatch, true);
287+
});
288+
await cut.InvokeAsync(() => cut.Instance.TriggerFilter("t"));
289+
menus = cut.FindAll(".dropdown-item");
290+
Assert.Single(menus);
248291
}
249292

250293
[Fact]

test/UnitTest/Components/SearchTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task ItemTemplate_Ok()
3333
});
3434
});
3535

36-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
36+
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
3737
await Task.Delay(20);
3838

3939
Assert.Contains("Template-test1-Address 1", cut.Markup);
@@ -54,7 +54,7 @@ public async Task OnGetDisplayText_Ok()
5454
pb.Add(a => a.OnGetDisplayText, foo => foo?.Name);
5555
});
5656

57-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
57+
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
5858
await Task.Delay(20);
5959

6060
Assert.Contains("test1", cut.Markup);
@@ -144,7 +144,7 @@ public async Task OnSelectedItemChanged_Ok()
144144
return items;
145145
});
146146
});
147-
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
147+
await cut.InvokeAsync(() => cut.Instance.TriggerChange("t"));
148148

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

0 commit comments

Comments
 (0)