Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.

Commit b010cd8

Browse files
authored
fix(TSelect): 修复无法选中下拉项和初始化时双向绑定可以自动选中项 (#306)
2 parents 05138c0 + 2595ce4 commit b010cd8

9 files changed

Lines changed: 182 additions & 86 deletions

File tree

doc/TDesign.Docs.ServerSide/TDesign.xml

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/TDesign.Docs.Shared/Pages/Components/Input/SelectPage.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
</CodeContent>
4747
</Example>
4848

49-
@code{
50-
int Value1{ get; set; }
49+
@code{
50+
int Value1 { get; set; } = 1;
5151
string Value2 { get; set; }
5252
}
5353

doc/TDesign.Docs.Shared/Pages/TestPage.razor

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,68 +2,13 @@
22
@using Test = TDesign.Docs.Shared.Pages.Components.Data.TablePage
33
@layout EmptyLayout
44

5-
<TMenu>
6-
<TMenuItem Link="/test">测试</TMenuItem>
7-
</TMenu>
8-
9-
@*<TPagination @bind-PageIndex="Page" @bind-PageSize=Size @bind-Total=Total/>
10-
11-
@code{
12-
int Page { get; set; } = 1;
13-
int Size { get; set; } = 3;
14-
int Total { get; set; } = 12;
15-
}
16-
*@
17-
@*<TPopup Content="弹出一个层">
18-
<TButton>悬浮</TButton>
19-
</TPopup>*@
20-
21-
@*<TTable TItem="Test.User" Data="Test.User.GetData()">
22-
<TTableExpandColumn>
23-
<h4>Name:@context.Name</h4>
24-
</TTableExpandColumn>
25-
<TTableCheckboxColumn Field="f=>f.Id" />
26-
<TTableFieldColumn Field="f=>f.Id" />
27-
<TTableFieldColumn Field="f=>f.Name" />
28-
<TTableFieldColumn Field="f=>f.Age" >
29-
<FooterContent>
30-
底部内容
31-
</FooterContent>
32-
</TTableFieldColumn>
33-
<TTableFieldColumn Field="f=>f.Gender" />
34-
35-
</TTable>
36-
37-
@code {
38-
IEnumerable<string> Text { get; set; } = Enumerable.Empty<string>();
39-
40-
void HandleKey(KeyboardEventArgs e)
41-
{
42-
43-
}
44-
}*@
45-
@*<TButton OnClick="e=>_dialog.Open()">
46-
弹框
47-
</TButton>
48-
<TDialog @ref="_dialog">
49-
让弹出框
50-
</TDialog>
51-
52-
@code{
53-
TDialog? _dialog;
54-
}*@
55-
@*
56-
@inject IDialogService DialogService
57-
58-
<TButton OnClick="Open">
59-
对话框
60-
</TButton>
61-
5+
<div style="width:180px">
6+
<TSelect @bind-Value="Value">
7+
<TSelectOption Value="1" Label="选项1">选项1</TSelectOption>
8+
<TSelectOption Value="2" Label="选项2">选项2</TSelectOption>
9+
</TSelect>
10+
</div>
6211

6312
@code{
64-
async Task Open()
65-
{
66-
var dialog = await DialogService.OpenInfo("第一个提示");
67-
}
68-
}
69-
@inject IJSRuntime JS*@
13+
int Value { get; set; } = 1;
14+
}

doc/TDesign.Docs.WebAssembly/wwwroot/TDesign.xml

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using Microsoft.AspNetCore.Components.Forms;
2+
using System.Linq.Expressions;
3+
4+
namespace TDesign;
5+
6+
/// <summary>
7+
/// 表单具备单项选择功能的组件基类。
8+
/// </summary>
9+
/// <typeparam name="TValue">值的类型。</typeparam>
10+
[ParentComponent(IsFixed = true)]
11+
[CascadingTypeParameter(nameof(TValue))]
12+
public abstract class SingleSelectionComponentBase<TValue> : TDesignChildContentComponentBase, IHasInputValue<TValue>
13+
{
14+
/// <summary>
15+
/// 执行当 <see cref="TInputRadio{TValue}"/> 触发的事件。
16+
/// </summary>
17+
[Parameter] public EventCallback<string> OnValueSelected { get; set; }
18+
19+
/// <summary>
20+
/// 内部事件,当 <see cref="TInputRadio{TValue}"/> 组件被点击发生改变时触发。
21+
/// </summary>
22+
internal EventCallback<ChangeEventArgs> ChangeEventCallback { get; set; }
23+
24+
/// <summary>
25+
/// Gets the selected value.
26+
/// </summary>
27+
internal TValue? SelectedValue => this.Value;
28+
29+
/// <inheritdoc/>
30+
[Parameter]public TValue? Value { get; set; }
31+
/// <inheritdoc/>
32+
[Parameter] public Expression<Func<TValue?>>? ValueExpression { get; set; }
33+
/// <inheritdoc/>
34+
[Parameter] public EventCallback<TValue?> ValueChanged { get; set; }
35+
[CascadingParameter]public EditContext? CascadedEditContext { get; set; }
36+
37+
/// <summary>
38+
/// 表示当组内的单选框发生变化时的通知。
39+
/// </summary>
40+
internal event Action NotifyOptionsRendered;
41+
string? _oldValue = default;
42+
43+
protected override void OnParametersSet()
44+
{
45+
base.OnParametersSet();
46+
47+
var newValue = this.GetValueAsString();
48+
ChangeEventCallback = EventCallback.Factory.CreateBinder<string?>(this, __value =>
49+
{
50+
this.GetCurrentValueAsString(__value);
51+
_ = OnValueSelected.InvokeAsync(__value);
52+
}
53+
, newValue);
54+
55+
if ( _oldValue != newValue )
56+
{
57+
_oldValue = newValue;
58+
NotifyOptionsRendered?.Invoke();
59+
}
60+
}
61+
}

src/TDesign/Components/Forms/TInputText.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ void BuildPrefixOrSuffix(RenderTreeBuilder builder, int sequence, string? text,
6767
}, !string.IsNullOrEmpty(text) || icon is not null);
6868
}
6969

70+
protected override string EventName => "onchange";
71+
7072
protected override void BuildAttributes(IDictionary<string, object> attributes)
7173
{
7274
base.BuildAttributes(attributes);

src/TDesign/Components/Forms/TSelect.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<ChildContent>
77
<div class="t-select__wrap">
88
<div class="@GetCssClassString()">
9-
<TInputText @bind-Value="SelectedLabel" Readonly SuffixIcon="@(RefPopup.Visible?IconName.ChevronUp:IconName.ChevronDown)" AutoWidth="AutoWidth" placeholder="@Placeholder" Disabled="Disabled" Size="Size"/>
9+
<TInputText @bind-Value="SelectedLabel" Readonly SuffixIcon="@(RefPopup.Visible?IconName.ChevronUp:IconName.ChevronDown)" AutoWidth="AutoWidth" placeholder="@Placeholder" Disabled="Disabled" Size="Size" />
1010

1111
</div>
1212
</div>

src/TDesign/Components/Forms/TSelect.razor.cs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using Microsoft.AspNetCore.Components.Rendering;
2-
3-
namespace TDesign;
1+
namespace TDesign;
42

53
/// <summary>
64
/// 用于收纳大量选项的信息录入类组件。
75
/// </summary>
86
/// <typeparam name="TValue">值的类型。</typeparam>
7+
[ParentComponent]
98
public partial class TSelect<TValue>
109
{
1110
/// <summary>
@@ -25,26 +24,43 @@ public partial class TSelect<TValue>
2524
/// <summary>
2625
/// Popup 组件的引用。
2726
/// </summary>
28-
TPopup? RefPopup { get; set; }
27+
internal TPopup? RefPopup { get; set; }
2928

3029
/// <summary>
3130
/// 选中的标签的值。
3231
/// </summary>
33-
string? SelectedLabel { get; set; }
32+
internal string? SelectedLabel { get; set; }
33+
34+
protected override async Task OnAfterRenderAsync(bool firstRender)
35+
{
36+
await base.OnAfterRenderAsync(firstRender);
37+
if ( firstRender )
38+
{
39+
if ( Value is not null )
40+
{
41+
var initialSelectedOption = ChildComponents.OfType<TSelectOption<TValue>>().FirstOrDefault(m => Value.Equals(m.Value));
42+
43+
if ( initialSelectedOption != null )
44+
{
45+
await SelectValue(initialSelectedOption.Value, initialSelectedOption.Label);
46+
await this.Refresh();
47+
}
48+
}
49+
}
50+
}
51+
3452

3553
/// <summary>
3654
/// 选择指定的值。
3755
/// </summary>
3856
/// <param name="value">选中的值。</param>
3957
/// <param name="label">选中的文本。</param>
40-
public Task? SelectValue(TValue? value, string? label)
58+
public async Task SelectValue(TValue? value, string? label)
4159
{
4260
Value = value;
43-
ValueChanged.InvokeAsync(value);
44-
OnValueSelected.InvokeAsync(value);
61+
await ValueChanged.InvokeAsync(value);
62+
await OnValueSelected.InvokeAsync(value);
4563
SelectedLabel = label;
46-
this.Refresh();
47-
return RefPopup?.Hide();
4864
}
4965

5066
protected override void BuildCssClass(ICssClassBuilder builder)
@@ -67,7 +83,7 @@ public class TSelectOption<TValue> : TDesignComponentBase, IHasChildContent
6783
/// <summary>
6884
/// 级联 <see cref="TSelect{TValue}"/> 组件。
6985
/// </summary>
70-
[CascadingParameter] protected TSelect<TValue> CascadingSelect { get; set; }
86+
[CascadingParameter] public TSelect<TValue> CascadingSelect { get; set; }
7187
/// <summary>
7288
/// 选项的值。
7389
/// </summary>
@@ -84,7 +100,7 @@ public class TSelectOption<TValue> : TDesignComponentBase, IHasChildContent
84100
/// <summary>
85101
/// 自定义选项的内容。
86102
/// </summary>
87-
[Parameter] public RenderFragment? ChildContent { get; set; }
103+
[Parameter] public RenderFragment? ChildContent { get; set; }
88104

89105
/// <inheritdoc/>
90106
protected override void OnParametersSet()
@@ -114,12 +130,13 @@ protected override void BuildCssClass(ICssClassBuilder builder)
114130
/// <inheritdoc/>
115131
protected override void BuildAttributes(IDictionary<string, object> attributes)
116132
{
117-
attributes["onclick"] = HtmlHelper.Instance.Callback().Create(this, () =>
133+
attributes["onclick"] = HtmlHelper.Instance.Callback().Create(this, async () =>
118134
{
119-
if (!Disabled)
135+
await CascadingSelect.SelectValue(Value, Label);
136+
if ( CascadingSelect.RefPopup is not null )
120137
{
121-
CascadingSelect.SelectValue(Value, Label);
138+
await CascadingSelect.RefPopup.Hide();
122139
}
123-
});
140+
}, !Disabled);
124141
}
125142
}

src/TDesign/TDesign.csproj

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
<SupportedPlatform Include="browser" />
4040
</ItemGroup>
4141
<ItemGroup>
42-
<PackageReference Include="ComponentBuilder" Version="4.1.0" />
43-
<PackageReference Include="ComponentBuilder.Extensions" Version="4.1.0" />
44-
<PackageReference Include="ComponentBuilder.FluentRenderTree" Version="4.1.0" />
45-
<PackageReference Include="ComponentBuilder.JSInterop" Version="4.1.0" />
42+
<PackageReference Include="ComponentBuilder" Version="4.1.2" />
43+
<PackageReference Include="ComponentBuilder.Extensions" Version="4.1.2" />
44+
<PackageReference Include="ComponentBuilder.FluentRenderTree" Version="4.1.2" />
45+
<PackageReference Include="ComponentBuilder.JSInterop" Version="4.1.2" />
4646
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
4747
<PackageReference Include="OneOf" Version="3.0.243" />
4848
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.51.0.59060">
@@ -126,6 +126,7 @@
126126
<Folder Include="JSInterop\" />
127127
</ItemGroup>
128128

129+
129130
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
130131
<Exec Command="rem(){ :;};rem '&#xD;&#xA;@goto b&#xD;&#xA;';&#xD;&#xA;echo sh;&#xD;&#xA;cp $(OutDir)TDesign.xml ..\..\doc\TDesign.Docs.ServerSide;&#xD;&#xA;cp $(OutDir)TDesign.xml ..\..\doc\TDesign.Docs.WebAssembly\wwwroot;&#xD;&#xA;exit&#xD;&#xA;&#xD;&#xA;:b&#xD;&#xA;copy $(OutDir)TDesign.xml ..\..\doc\TDesign.Docs.ServerSide&#xD;&#xA;copy $(OutDir)TDesign.xml ..\..\doc\TDesign.Docs.WebAssembly\wwwroot" />
131132
</Target>

0 commit comments

Comments
 (0)