Blazor:在使用 @bind 时如何在 <select> 中使用 onchange 事件?
Posted
技术标签:
【中文标题】Blazor:在使用 @bind 时如何在 <select> 中使用 onchange 事件?【英文标题】:Blazor: How to use the onchange event in <select> when using @bind also? 【发布时间】:2020-01-27 06:30:46 【问题描述】:在<select>
中进行选择后,我需要能够运行函数。问题是我也绑定了@bind,当我尝试使用@onchange 时出现错误,指出它已被@bind 使用。我尝试使用@onselectionchange,但这什么也没做(不运行该功能)。我可能会忘记@bind,而只是将@onchange 分配给一个函数,但我不确定如何将选定的值传递给函数。
我有以下代码:
<select @bind="@SelectedCustID" @ @onchange="@CustChanged" class="form-control">
@foreach (KeyGuidPair i in CustList)
<option value="@i.Value">@i.Text</option>
</select>
谢谢。
【问题讨论】:
只是附注:您可以使用@bind=SelectedCustID
代替@bind="@SelectedCustID"
。它更干净:)
一个字符@
好像是多余的。
见***.com/questions/58452319/…
【参考方案1】:
<select @bind="MyProperty">
<option>Your Option<option>
</select>
@code
private string myVar;
public string MyProperty
get return myVar;
set
myVar = value;
SomeMethod();
private void SomeMethod()
//Do something
【讨论】:
这可行,但如果您需要进行一些异步调用,例如数据库更新,则会出现问题...... @Alexandre,我认为您可以使用.Wait()
将异步调用转换为同步调用。见here。
应该选择不输入,因为用户要求选择代码。【参考方案2】:
@bind
本质上等同于同时拥有value
和@onchange
,例如:
<input @bind="CurrentValue" />
相当于:
<input value="@CurrentValue" @onchange="@((ChangeEventArgs e) => CurrentValue = e.Value.ToString())" />
由于您已经定义了@onchange
,所以不要同时添加@bind
,只需添加value
以防止冲突:
<select value="@SelectedCustID" @onchange="@CustChanged" class="form-control">
@foreach (KeyGuidPair i in CustList)
<option value="@i.Value">@i.Text</option>
</select>
来源:https://docs.microsoft.com/en-us/aspnet/core/blazor/components/data-binding?view=aspnetcore-3.1
【讨论】:
只是提到你的解释,你说“相当于”帮助我弄清楚如何在 blazor select 的 onchange 事件上传递多个参数。谢谢。【参考方案3】:这似乎是一个普遍的困惑。首先你不能使用@onchange
,因为它会被@bind
在内部使用。您应该能够从 CustChanged
属性的设置器中访问选定的值。根据您尝试对 CustChanged
执行的操作,您甚至可能不需要手动检查此值何时更新。例如,如果您的意图是在您的 UI 中直接或间接使用 CustChanged
(在 Linq 或其他东西中),则当您的 <select>
更改时,UI 将自动更新为 CustChanged
值。因此,对于大多数用例,我认为不需要检查它何时更新。
要使用@onchange
,您可以将其绑定到类似这样的函数:
public void OnUpdated(ChangeEventArgs e)
var selected = e.Value;
【讨论】:
这是对所提问题的正确答案。 令人讨厌的是,这似乎实际上是选择了选项文本,而不是选项值【参考方案4】:您可以完全避免使用@bind
(如果您使用的是foreach
):
<select @onchange=@(handleChange)>
@foreach (var option in _options)
<option value=@option.Id selected=@(SelectedId == option.Id)>@option.Name</option>
</select>
@code
public record Person(int Id, string Name);
public int SelectedId get; set;
public List<Person> _options = new List<Person>()
new Person(1,"A"),
new Person(2,"B"),
new Person(3,"C")
;
public void handleChange(ChangeEventArgs args)
Console.WriteLine(args.Value);
SelectedId = Int32.Parse(args.Value.ToString());
一些肮脏的细节:在尝试将 F# 与服务器端 Blazor 一起使用时,我遇到了一些奇怪的行为。简而言之,将选项的 List
设置为实体框架查询的结果(映射到记录列表)不会正确地 @bind
,而是使用 C# 类而不是 F# 记录的虚拟选项列表 确实工作。但这不是因为它是记录,因为如果我将列表设置为 EF 查询,然后立即将其设置为虚拟记录列表,它仍然没有正确地 @bind
- 但它 确实 如果我注释掉 EF 行,就可以工作。
【讨论】:
true 或 false 对所选属性无效***.com/questions/1033944/… @Alexandre True。但是,Blazor 将selected=true/false
转换为有效的 html。 i.imgur.com/QEDQceP.png 同样适用于其他属性,例如 disabled
: ***.com/questions/55002514/… 也 blazor-university.com/components/code-generated-html-attributes
嗨 DharmaTurlte 能否请您详细说明@onchange=@(x => ...)。 lambda 表达式有什么用途。我必须在那里写什么代码(方法调用?如何?)。谢谢
@nogood 我填写了 lambda。如果您仍然感到困惑,请 LMK。【参考方案5】:
只需添加@bind-value 和@bind-vale:event 和@onchnage,如下所示。注意小写字母。这对我有用,没有任何问题。
<select @bind-value="variablenametokeepselectedvalue" @onchange="yourmethodname" @bind-value:event="oninput">
<option value="1">Test</option>
</select>
【讨论】:
【参考方案6】:请检查此示例。它正在使用 @bind 但在设置值时会触发 @onchange 事件
<div class="form-group">
<label for="client">Client Name</label>
<select id="client" @bind="CheckSelected" class="form-control">
<option value="selected1">selected1</option>
<option value="selected2">selected2</option>
</select>
</div>
@code 私有字符串 selectedItem get;放; 私有字符串 CheckSelected 得到 返回选中项; 放 ChangeEventArgs selectedEventArgs = new ChangeEventArgs(); selectedEventArgs.Value = 值; OnChangeSelected(selectedEventArgs); 私人无效 OnChangeSelected(ChangeEventArgs e) if (e.Value.ToString() != string.Empty) selectedItem = e.Value.ToString();
【讨论】:
值得注意的是,此解决方案适用于 blazorEditForm
(***.com/questions/61756167/…),因为 InputSelect
无法通过以下方式正确绑定事件:<InputSelect Id="Source" @bind-Value="@model.Source" Class="form-control" @onchange="HandleSourceOptionChanged">
。【参考方案7】:
如果可能,我的建议是在表单元素周围使用 EditForm 包装器。然后,您可以在一个地方检测到任何表单元素的变化。例如,这适用于一堆搜索过滤器。任何过滤器的任何更改都应触发对数据的另一次查询,等等。
如何在表单更改时触发事件的示例在这里:
blazor editform change events
【讨论】:
【参考方案8】:<div class="form-group">
<label for="client">Client Name</label>
<select class="form-control" @onchange="@((e) => myVar = e.Value.ToString(); MyMethod(); )">
<option value="val1">val1</option>
<option value="val2">val2</option>
</select>
</div>
这就是我在@onchange 事件中调用方法时设置属性的方式。
-Blazor 服务器 -Dotnet Core 3.1
【讨论】:
【参考方案9】:根据Microsoft's documentation,这是他们处理此问题的首选方式:
<InputText Value="@NewPaymentAmount" class="mdl-textfield__input"
ValueExpression="() => NewPaymentAmount"
ValueChanged="(string value) => ValidateAmount(value)" />
private void ValidateAmount(string amount)
NewPaymentAmount = amount;
// Do validation or whatever
或者async
方式:
<InputText Value="@NewPaymentAmount" class="mdl-textfield__input"
ValueExpression="() => NewPaymentAmount"
ValueChanged="async (string value) => await ValidateAmountAsync(value)" />
private async Task ValidateAmountAsync(string amount)
NewPaymentAmount = amount;
// Do validation or whatever
【讨论】:
以上是关于Blazor:在使用 @bind 时如何在 <select> 中使用 onchange 事件?的主要内容,如果未能解决你的问题,请参考以下文章