Skip to content

Commit b179a1f

Browse files
authored
feat(Select): add DefaultVirtualizeItemText parameter (#2020)
* feat: 虚拟化时支持绑定值 * feat: 支持虚拟化给定默认值 * test: 增加单元测试 * refactor: 更新代码 * test: 更新单元测试 * chore: bump version 7.9.4-beta01
1 parent f759f29 commit b179a1f

File tree

3 files changed

+97
-6
lines changed

3 files changed

+97
-6
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>7.9.3</Version>
4+
<Version>7.9.4-beta01</Version>
55
</PropertyGroup>
66

77
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">

src/BootstrapBlazor/Components/Select/Select.razor.cs

+16-5
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ public partial class Select<TValue> : ISelect
151151
[Parameter]
152152
public int OverscanCount { get; set; } = 4;
153153

154+
/// <summary>
155+
/// 获得/设置 默认文本 <see cref="IsVirtualize"/> 时生效 默认 null
156+
/// </summary>
157+
/// <remarks>开启 <see cref="IsVirtualize"/> 并且通过 <see cref="OnQueryAsync"/> 提供数据源时,由于渲染时还未调用或者调用后数据集未包含 <see cref="DisplayBase{TValue}.Value"/> 选项值,此时使用 DefaultText 值渲染</remarks>
158+
[Parameter]
159+
public string? DefaultVirtualizeItemText { get; set; }
160+
154161
[NotNull]
155162
private Virtualize<SelectedItem>? VirtualizeElement { get; set; }
156163

@@ -254,14 +261,16 @@ protected override bool TryParseValueFromString(string value, [MaybeNullWhen(fal
254261

255262
private bool TryParseSelectItem(string value, [MaybeNullWhen(false)] out TValue result, out string? validationErrorMessage)
256263
{
257-
SelectedItem = (VirtualItems ?? DataSource).FirstOrDefault(i => i.Value == value);
264+
SelectedItem = (VirtualItems ?? DataSource).FirstOrDefault(i => i.Value == value) ?? GetVirtualizeItem();
258265

259266
// support SelectedItem? type
260267
result = SelectedItem != null ? (TValue)(object)SelectedItem : default;
261268
validationErrorMessage = "";
262269
return SelectedItem != null;
263270
}
264271

272+
private SelectedItem? GetVirtualizeItem() => OnQueryAsync == null ? null : ValueType == typeof(SelectedItem) ? (SelectedItem)(object)Value : new SelectedItem(CurrentValueAsString, DefaultVirtualizeItemText ?? CurrentValueAsString);
273+
265274
private void ResetSelectedItem()
266275
{
267276
DataSource.Clear();
@@ -270,14 +279,16 @@ private void ResetSelectedItem()
270279
{
271280
DataSource.AddRange(Items);
272281
DataSource.AddRange(Children);
282+
273283
if (VirtualItems != null)
274284
{
275285
DataSource.AddRange(VirtualItems);
276286
}
277287

278288
SelectedItem = DataSource.FirstOrDefault(i => i.Value.Equals(CurrentValueAsString, StringComparison))
279289
?? DataSource.FirstOrDefault(i => i.Active)
280-
?? DataSource.FirstOrDefault();
290+
?? DataSource.FirstOrDefault()
291+
?? GetVirtualizeItem();
281292

282293
if (SelectedItem != null)
283294
{
@@ -365,14 +376,14 @@ private async Task SelectedItemChanged(SelectedItem item)
365376
item.Active = true;
366377
SelectedItem = item;
367378

368-
// 触发 StateHasChanged
369-
CurrentValueAsString = item.Value;
370-
371379
// 触发 SelectedItemChanged 事件
372380
if (OnSelectedItemChanged != null)
373381
{
374382
await OnSelectedItemChanged(SelectedItem);
375383
}
384+
385+
// 触发 StateHasChanged
386+
CurrentValueAsString = item.Value;
376387
}
377388
}
378389

test/UnitTest/Components/SelectTest.cs

+80
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,86 @@ public void IsVirtualize_OnQueryAsync()
608608
});
609609
}
610610

611+
[Fact]
612+
public void IsVirtualize_BindValue()
613+
{
614+
var value = new SelectedItem("3", "Test 3");
615+
var cut = Context.RenderComponent<Select<SelectedItem>>(pb =>
616+
{
617+
pb.Add(a => a.Value, value);
618+
pb.Add(a => a.IsVirtualize, true);
619+
pb.Add(a => a.ValueChanged, EventCallback.Factory.Create<SelectedItem>(this, new Action<SelectedItem>(item =>
620+
{
621+
value = item;
622+
})));
623+
pb.Add(a => a.OnQueryAsync, option =>
624+
{
625+
return Task.FromResult(new QueryData<SelectedItem>()
626+
{
627+
Items = new SelectedItem[]
628+
{
629+
new SelectedItem("1", "Test1"),
630+
new SelectedItem("2", "Test2")
631+
},
632+
TotalCount = 2
633+
});
634+
});
635+
});
636+
637+
cut.InvokeAsync(() =>
638+
{
639+
var input = cut.Find(".form-select");
640+
Assert.Equal("Test 3", input.GetAttribute("value"));
641+
});
642+
cut.Contains("Test 3");
643+
var select = cut.Instance;
644+
Assert.Equal("3", select.Value?.Value);
645+
646+
cut.InvokeAsync(() =>
647+
{
648+
var item = cut.Find(".dropdown-item");
649+
item.Click();
650+
Assert.Equal("1", value.Value);
651+
652+
var input = cut.Find(".form-select");
653+
Assert.Equal("Test1", input.GetAttribute("value"));
654+
});
655+
}
656+
657+
[Fact]
658+
public void IsVirtualize_DefaultVirtualizeItemText()
659+
{
660+
string value = "3";
661+
var cut = Context.RenderComponent<Select<string>>(pb =>
662+
{
663+
pb.Add(a => a.IsVirtualize, true);
664+
pb.Add(a => a.DefaultVirtualizeItemText, "Test 3");
665+
pb.Add(a => a.Value, value);
666+
pb.Add(a => a.ValueChanged, EventCallback.Factory.Create<string>(this, new Action<string>(item =>
667+
{
668+
value = item;
669+
})));
670+
pb.Add(a => a.OnQueryAsync, option =>
671+
{
672+
return Task.FromResult(new QueryData<SelectedItem>()
673+
{
674+
Items = new SelectedItem[]
675+
{
676+
new SelectedItem("1", "Test1"),
677+
new SelectedItem("2", "Test2")
678+
},
679+
TotalCount = 2
680+
});
681+
});
682+
});
683+
684+
cut.InvokeAsync(() =>
685+
{
686+
var input = cut.Find(".form-select");
687+
Assert.Equal("Test 3", input.GetAttribute("value"));
688+
});
689+
}
690+
611691
[Fact]
612692
public void LoadItems_Ok()
613693
{

0 commit comments

Comments
 (0)