From 9062da8036055643922f292d8cfa9b3c15b860a2 Mon Sep 17 00:00:00 2001 From: T1246 Date: Fri, 14 Mar 2025 13:51:49 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E5=AF=B9Select=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BF=AE=E6=94=B9=EF=BC=8C=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?IsClearable=E5=90=8E=EF=BC=8C=E5=A6=82=E6=9E=9C=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E7=B1=BB=E5=9E=8B=E5=8F=AF=E4=BB=A5=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=EF=BC=8C=E6=B8=85=E9=99=A4=E5=90=8E=E6=B8=85=E6=A5=9A=E6=89=80?= =?UTF-8?q?=E6=9C=89=E9=80=89=E4=B8=AD=E9=A1=B9=E8=80=8C=E4=B8=8D=E6=98=AF?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Select/Select.razor.cs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/BootstrapBlazor/Components/Select/Select.razor.cs b/src/BootstrapBlazor/Components/Select/Select.razor.cs index 18766cbd51a..dac90184be7 100644 --- a/src/BootstrapBlazor/Components/Select/Select.razor.cs +++ b/src/BootstrapBlazor/Components/Select/Select.razor.cs @@ -294,12 +294,15 @@ private SelectedItem? SelectedRow private SelectedItem? GetSelectedRow() { + + var canBeNull = ValueCanBeNull(); var item = GetItemWithEnumValue() ?? Rows.Find(i => i.Value == CurrentValueAsString) ?? Rows.Find(i => i.Active) - ?? Rows.FirstOrDefault(i => !i.IsDisabled) + ?? Rows.FirstOrDefault(i => !i.IsDisabled&&!canBeNull) ?? GetVirtualizeItem(CurrentValueAsString); - + + if (item != null) { if (_init && DisableItemChangedWhenFirstRender) @@ -576,7 +579,26 @@ private async Task OnClearValue() { await OnClearAsync(); } + + if (ValueCanBeNull()) + { + + if (SelectedItem != null) SelectedItem.Active = false; + SelectedItem = null; + // 触发 StateHasChanged + _lastSelectedValueString = string.Empty; + CurrentValueAsString = _lastSelectedValueString; + this.Value = default; + if (this.ValueChanged.HasDelegate) + await this.ValueChanged.InvokeAsync(default); + // 触发 SelectedItemChanged 事件--由于设置成了null + //if (OnSelectedItemChanged != null) + //{ + // await OnSelectedItemChanged(SelectedItem); + //} + return; + } SelectedItem? item; if (OnQueryAsync != null) { @@ -592,7 +614,11 @@ private async Task OnClearValue() await SelectedItemChanged(item); } } - + private bool ValueCanBeNull() + { + var tType = typeof(TValue); + return !tType.IsValueType || Nullable.GetUnderlyingType(tType) != null; + } private string? ReadonlyString => IsEditable ? null : "readonly"; private async Task OnChange(ChangeEventArgs args) From 569a38e1ebfa3a3892b7f10bb34b890035f75330 Mon Sep 17 00:00:00 2001 From: T1246 Date: Fri, 14 Mar 2025 19:24:01 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dyige=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Components/Select/Select.razor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/BootstrapBlazor/Components/Select/Select.razor.cs b/src/BootstrapBlazor/Components/Select/Select.razor.cs index dac90184be7..a36cb625ae4 100644 --- a/src/BootstrapBlazor/Components/Select/Select.razor.cs +++ b/src/BootstrapBlazor/Components/Select/Select.razor.cs @@ -585,7 +585,11 @@ private async Task OnClearValue() if (SelectedItem != null) SelectedItem.Active = false; SelectedItem = null; - + if (Items != null) //数据中存在多个IsActive= true的 需要都清空 + foreach (var nowItems in Items) + { + nowItems.Active = false; + } // 触发 StateHasChanged _lastSelectedValueString = string.Empty; CurrentValueAsString = _lastSelectedValueString; From 48ffa8c2ee97426a53f13e7b317b2767a9373b81 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 14 Mar 2025 23:52:56 +0800 Subject: [PATCH 03/12] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E5=8F=AF?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Select/Select.razor.cs | 63 +++++-------------- 1 file changed, 16 insertions(+), 47 deletions(-) diff --git a/src/BootstrapBlazor/Components/Select/Select.razor.cs b/src/BootstrapBlazor/Components/Select/Select.razor.cs index a36cb625ae4..81f530c191d 100644 --- a/src/BootstrapBlazor/Components/Select/Select.razor.cs +++ b/src/BootstrapBlazor/Components/Select/Select.razor.cs @@ -42,7 +42,7 @@ public partial class Select : ISelect, ILookup .AddClass($"text-danger", IsValid.HasValue && !IsValid.Value) .Build(); - private bool GetClearable() => IsClearable && !IsDisabled; + private bool GetClearable() => IsClearable && !IsDisabled && IsNullable(); /// /// 设置当前项是否 Active 方法 @@ -294,15 +294,17 @@ private SelectedItem? SelectedRow private SelectedItem? GetSelectedRow() { - - var canBeNull = ValueCanBeNull(); + if (Value is null) + { + return null; + } + var item = GetItemWithEnumValue() ?? Rows.Find(i => i.Value == CurrentValueAsString) ?? Rows.Find(i => i.Active) - ?? Rows.FirstOrDefault(i => !i.IsDisabled&&!canBeNull) + ?? Rows.FirstOrDefault(i => !i.IsDisabled) ?? GetVirtualizeItem(CurrentValueAsString); - - + if (item != null) { if (_init && DisableItemChangedWhenFirstRender) @@ -396,7 +398,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// private int TotalCount { get; set; } - private List GetVirtualItems() => FilterBySearchText(GetRowsByItems()).ToList(); + private List GetVirtualItems() => [.. FilterBySearchText(GetRowsByItems())]; /// /// 虚拟滚动数据加载回调方法 @@ -542,7 +544,6 @@ private async Task SelectedItemChanged(SelectedItem item) { if (_lastSelectedValueString != item.Value) { - item.Active = true; SelectedItem = item; @@ -559,7 +560,7 @@ private async Task SelectedItemChanged(SelectedItem item) } /// - /// 添加静态下拉项方法 + /// /// /// public void Add(SelectedItem item) => _children.Add(item); @@ -579,50 +580,18 @@ private async Task OnClearValue() { await OnClearAsync(); } - - if (ValueCanBeNull()) - { - if (SelectedItem != null) SelectedItem.Active = false; - SelectedItem = null; - if (Items != null) //数据中存在多个IsActive= true的 需要都清空 - foreach (var nowItems in Items) - { - nowItems.Active = false; - } - // 触发 StateHasChanged - _lastSelectedValueString = string.Empty; - CurrentValueAsString = _lastSelectedValueString; - this.Value = default; - if (this.ValueChanged.HasDelegate) - await this.ValueChanged.InvokeAsync(default); - // 触发 SelectedItemChanged 事件--由于设置成了null - //if (OnSelectedItemChanged != null) - //{ - // await OnSelectedItemChanged(SelectedItem); - //} - return; - } - SelectedItem? item; if (OnQueryAsync != null) { await VirtualizeElement.RefreshDataAsync(); - item = _result.Items.FirstOrDefault(); } - else - { - item = Items.FirstOrDefault(); - } - if (item != null) - { - await SelectedItemChanged(item); - } - } - private bool ValueCanBeNull() - { - var tType = typeof(TValue); - return !tType.IsValueType || Nullable.GetUnderlyingType(tType) != null; + + _lastSelectedValueString = string.Empty; + CurrentValue = default; } + + private bool IsNullable() => !ValueType.IsValueType || NullableUnderlyingType != null; + private string? ReadonlyString => IsEditable ? null : "readonly"; private async Task OnChange(ChangeEventArgs args) From e70395e87c90237498f42f45a45b352d0f9fab4b Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 14 Mar 2025 23:53:07 +0800 Subject: [PATCH 04/12] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/SelectTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/UnitTest/Components/SelectTest.cs b/test/UnitTest/Components/SelectTest.cs index b6ab38eaee4..f671478aa08 100644 --- a/test/UnitTest/Components/SelectTest.cs +++ b/test/UnitTest/Components/SelectTest.cs @@ -434,8 +434,7 @@ public void NullBool_Ok() }); // 值为 null - // 候选项中无,导致默认选择第一个 Value 被更改为 true - Assert.True(cut.Instance.Value); + Assert.Null(cut.Instance.Value); } [Fact] From cabdbf9d66d6c97afdd8c35dfbc7327e2fc30127 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 14 Mar 2025 23:53:16 +0800 Subject: [PATCH 05/12] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/Selects.razor | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor index 7359fb578e5..969efb6824e 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor @@ -412,22 +412,23 @@ -
@((MarkupString)Localizer["SelectsVirtualizeDescription"].Value)
- -
-
- - - - -
-
- - - - +
+

@((MarkupString)Localizer["SelectsVirtualizeDescription"].Value)

+
+
+ + + + +
+
+ + + + +
-
+

1. 使用 OnQueryAsync 作为数据源

From 7f0ee584284d591142f53c8a52a540940fea54f3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 09:31:50 +0800 Subject: [PATCH 06/12] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20readonly?= =?UTF-8?q?=20=E5=85=B3=E9=94=AE=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs index ace25321957..a4ad8226e41 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs @@ -51,7 +51,7 @@ public sealed partial class Selects private string? _fooName; - private List _enumValueDemoItems = [ + private readonly List _enumValueDemoItems = [ new("0", "Primary"), new("1", "Middle") ]; From cb94702051f11c40cf370081bfae33805bcc2643 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 09:32:09 +0800 Subject: [PATCH 07/12] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/SelectTest.cs | 97 ++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/test/UnitTest/Components/SelectTest.cs b/test/UnitTest/Components/SelectTest.cs index f671478aa08..872cbf10c97 100644 --- a/test/UnitTest/Components/SelectTest.cs +++ b/test/UnitTest/Components/SelectTest.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Components.Web.Virtualization; using System.ComponentModel.DataAnnotations; using System.Reflection; +using System.Runtime.CompilerServices; namespace UnitTest.Components; @@ -176,6 +177,102 @@ public void IsClearable_Ok() Assert.Contains("text-danger", val); } + [Fact] + public void IsNullable_NotNullableString_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Items, new List() + { + new("", "请选择"), + new("2", "Test2"), + new("3", "Test3") + }); + }); + Assert.True(IsNullable(cut.Instance)); + } + + [Fact] + public void IsNullable_NullableString_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Items, new List() + { + new("", "请选择"), + new("2", "Test2"), + new("3", "Test3") + }); + }); + Assert.True(IsNullable(cut.Instance)); + } + + [Fact] + public void IsNullable_NotNullableFoo_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Items, new List() + { + new("", "请选择"), + new("2", "Test2"), + new("3", "Test3") + }); + }); + Assert.False(IsNullable(cut.Instance)); + } + + [Fact] + public void IsNullable_NullableFoo_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Items, new List() + { + new("", "请选择"), + new("2", "Test2"), + new("3", "Test3") + }); + }); + Assert.True(IsNullable(cut.Instance)); + } + + [Fact] + public void IsNullable_NotNullableInt_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Items, new List() + { + new("", "请选择"), + new("2", "Test2"), + new("3", "Test3") + }); + }); + Assert.False(IsNullable(cut.Instance)); + } + + [Fact] + public void IsNullable_NullableInt_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Items, new List() + { + new("", "请选择"), + new("2", "Test2"), + new("3", "Test3") + }); + }); + Assert.True(IsNullable(cut.Instance)); + } + + private static bool IsNullable(object select) + { + var mi = select.GetType().GetMethod("IsNullable", BindingFlags.Instance | BindingFlags.NonPublic)!; + return (bool)mi.Invoke(select, null)!; + } + [Fact] public void SelectOption_Ok() { From 40b041d53aea9a92a3e95d30320bdf94fd6b817b Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 09:46:05 +0800 Subject: [PATCH 08/12] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/SelectTest.cs | 42 +++++++------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/test/UnitTest/Components/SelectTest.cs b/test/UnitTest/Components/SelectTest.cs index 872cbf10c97..6aee78fd135 100644 --- a/test/UnitTest/Components/SelectTest.cs +++ b/test/UnitTest/Components/SelectTest.cs @@ -178,7 +178,7 @@ public void IsClearable_Ok() } [Fact] - public void IsNullable_NotNullableString_Ok() + public void IsNullable_Ok() { var cut = Context.RenderComponent>(pb => { @@ -190,12 +190,8 @@ public void IsNullable_NotNullableString_Ok() }); }); Assert.True(IsNullable(cut.Instance)); - } - [Fact] - public void IsNullable_NullableString_Ok() - { - var cut = Context.RenderComponent>(pb => + var cut1 = Context.RenderComponent>(pb => { pb.Add(a => a.Items, new List() { @@ -204,13 +200,9 @@ public void IsNullable_NullableString_Ok() new("3", "Test3") }); }); - Assert.True(IsNullable(cut.Instance)); - } + Assert.True(IsNullable(cut1.Instance)); - [Fact] - public void IsNullable_NotNullableFoo_Ok() - { - var cut = Context.RenderComponent>(pb => + var cut2 = Context.RenderComponent>(pb => { pb.Add(a => a.Items, new List() { @@ -219,13 +211,9 @@ public void IsNullable_NotNullableFoo_Ok() new("3", "Test3") }); }); - Assert.False(IsNullable(cut.Instance)); - } + Assert.True(IsNullable(cut2.Instance)); - [Fact] - public void IsNullable_NullableFoo_Ok() - { - var cut = Context.RenderComponent>(pb => + var cut3 = Context.RenderComponent>(pb => { pb.Add(a => a.Items, new List() { @@ -234,13 +222,9 @@ public void IsNullable_NullableFoo_Ok() new("3", "Test3") }); }); - Assert.True(IsNullable(cut.Instance)); - } + Assert.True(IsNullable(cut3.Instance)); - [Fact] - public void IsNullable_NotNullableInt_Ok() - { - var cut = Context.RenderComponent>(pb => + var cut4 = Context.RenderComponent>(pb => { pb.Add(a => a.Items, new List() { @@ -249,13 +233,9 @@ public void IsNullable_NotNullableInt_Ok() new("3", "Test3") }); }); - Assert.False(IsNullable(cut.Instance)); - } + Assert.False(IsNullable(cut4.Instance)); - [Fact] - public void IsNullable_NullableInt_Ok() - { - var cut = Context.RenderComponent>(pb => + var cut5 = Context.RenderComponent>(pb => { pb.Add(a => a.Items, new List() { @@ -264,7 +244,7 @@ public void IsNullable_NullableInt_Ok() new("3", "Test3") }); }); - Assert.True(IsNullable(cut.Instance)); + Assert.True(IsNullable(cut5.Instance)); } private static bool IsNullable(object select) From 7189486ad058f381bbb7913b9f1052936ae31467 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 09:46:20 +0800 Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20=E9=87=8D=E7=BD=AE=20Selected?= =?UTF-8?q?Item?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Components/Select/Select.razor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BootstrapBlazor/Components/Select/Select.razor.cs b/src/BootstrapBlazor/Components/Select/Select.razor.cs index 81f530c191d..1fb848e459a 100644 --- a/src/BootstrapBlazor/Components/Select/Select.razor.cs +++ b/src/BootstrapBlazor/Components/Select/Select.razor.cs @@ -588,6 +588,7 @@ private async Task OnClearValue() _lastSelectedValueString = string.Empty; CurrentValue = default; + SelectedItem = null; } private bool IsNullable() => !ValueType.IsValueType || NullableUnderlyingType != null; From 9603422f8bfd85e1549817e4e3ea966ee7cca1fb Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 09:46:28 +0800 Subject: [PATCH 10/12] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/Selects.razor | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor index 969efb6824e..ce342df5008 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor @@ -87,19 +87,6 @@
- -
-
- -
-
- -
-
-
- @@ -348,6 +335,19 @@
+ +
+
+ +
+
+ +
+
+
+ From 4e582243ddd3b23075b6971093eb683de8e84a8d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 10:43:36 +0800 Subject: [PATCH 11/12] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/Selects.razor | 13 ++++++++++-- .../Components/Samples/Selects.razor.cs | 21 ++++++++++++++++++- src/BootstrapBlazor.Server/Locales/en-US.json | 1 + src/BootstrapBlazor.Server/Locales/zh-CN.json | 1 + 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor index ce342df5008..4b5b6c51e44 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor @@ -338,12 +338,21 @@ +
+

@((MarkupString)Localizer["SelectsClearableDesc"].Value)

+
- + +
+
+ +
+
+
- +
diff --git a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs index a4ad8226e41..11332afc37b 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Selects.razor.cs @@ -101,7 +101,18 @@ private Task OnItemChanged(SelectedItem item) private Foo BindingModel { get; set; } = new Foo(); - private Foo ClearableModel { get; set; } = new Foo(); + private MockModel ClearableModel { get; set; } = new(); + + class MockModel + { + public string? NullableName { get; set; } + + public string Name { get; set; } = ""; + + public int Count { get; set; } = 1; + + public int? NullableCount { get; set; } + } private SelectedItem? Item { get; set; } @@ -230,6 +241,14 @@ private string GetSelectedBoolItemString() new("abcde", "abcde") ]; + private readonly SelectedItem[] IntItems = + [ + new("1", "1"), + new("12", "12"), + new("123", "123"), + new("1234", "1234") + ]; + private static Task OnBeforeSelectedItemChange(SelectedItem item) { return Task.FromResult(true); diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index b9af6258e8f..3636abe6d2b 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -3111,6 +3111,7 @@ "SelectsBindingIntro": "The values in the text box change as you change the drop-down option by binding the Model.Name property to the component with Select", "SelectsClearableTitle": "Clearable", "SelectsClearableIntro": "You can clear Select using a clear icon", + "SelectsClearableDesc": "Cannot be a null integer. Setting IsClearable has no effect. Its default value is 0", "SelectsBindingSelectedItemTitle": "Select two-way binding SelectItem type", "SelectsBindingSelectedItemIntro": "The values in the text box change as you change the drop-down option by binding the SelectItem property to the component with Select .", "SelectsCascadingTitle": "Select cascading binding", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 9f0918a687f..d1f1067eeca 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -3111,6 +3111,7 @@ "SelectsBindingIntro": "通过 Select 组件绑定 Model.Name 属性,改变下拉框选项时,文本框内的数值随之改变。", "SelectsClearableTitle": "可清空单选", "SelectsClearableIntro": "包含清空按钮,可将选择器清空为初始状态", + "SelectsClearableDesc": "不可为空整形设置 IsClearable 无效,其默认值为 0", "SelectsBindingSelectedItemTitle": "Select 双向绑定 SelectItem", "SelectsBindingSelectedItemIntro": "通过 Select 组件绑定 SelectItem 属性,改变下拉框选项时,文本框内的数值随之改变。", "SelectsCascadingTitle": "Select 级联绑定", From 37d3326d5d92bfcb95e55d9d6e6c2d8e3dd718db Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 15 Mar 2025 10:52:34 +0800 Subject: [PATCH 12/12] =?UTF-8?q?test:=20=E5=A2=9E=E5=8A=A0=E4=B8=8D?= =?UTF-8?q?=E5=8F=AF=E4=B8=BA=E7=A9=BA=E6=95=B4=E5=BD=A2=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=20IsClearable=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/SelectTest.cs | 29 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/test/UnitTest/Components/SelectTest.cs b/test/UnitTest/Components/SelectTest.cs index 6aee78fd135..f1c59c44c6d 100644 --- a/test/UnitTest/Components/SelectTest.cs +++ b/test/UnitTest/Components/SelectTest.cs @@ -135,7 +135,7 @@ public void Select_Lookup() } [Fact] - public void IsClearable_Ok() + public async Task IsClearable_Ok() { var val = "Test2"; var cut = Context.RenderComponent>(pb => @@ -155,8 +155,8 @@ public void IsClearable_Ok() }); }); var clearButton = cut.Find(".clear-icon"); - cut.InvokeAsync(() => clearButton.Click()); - Assert.Empty(val); + await cut.InvokeAsync(() => clearButton.Click()); + Assert.Null(val); // 提高代码覆盖率 var select = cut; @@ -175,6 +175,21 @@ public void IsClearable_Ok() validPi.SetValue(select.Instance, false); val = pi.GetValue(select.Instance, null)!.ToString(); Assert.Contains("text-danger", val); + + // 更改数据类型为不可为空 int + // IsClearable 参数无效 + var cut1 = Context.RenderComponent>(pb => + { + pb.Add(a => a.IsClearable, true); + pb.Add(a => a.Items, new List() + { + new("1", "Test1"), + new("2", "Test2"), + new("3", "Test3") + }); + pb.Add(a => a.Value, 1); + }); + cut1.DoesNotContain("clear-icon"); } [Fact] @@ -811,8 +826,8 @@ public async Task IsVirtualize_Items_Clearable_Ok() var button = cut.Find(".clear-icon"); await cut.InvokeAsync(() => button.Click()); - // UI 恢复 Test1 - Assert.Equal("Test1", el.Value); + // 可为空数据类型 UI 为 "" + Assert.Equal("", el.Value); // 下拉框显示所有选项 items = cut.FindAll(".dropdown-item"); @@ -870,8 +885,8 @@ public async Task IsVirtualize_OnQueryAsync_Clearable_Ok() var button = cut.Find(".clear-icon"); await cut.InvokeAsync(() => button.Click()); - // UI 恢复 Test1 - Assert.Equal("All", el.Value); + // 可为空数据类型 UI 为 "" + Assert.Equal("", el.Value); // 下拉框显示所有选项 Assert.True(query);