如何在Blazor组件上进行双向绑定 [英] How to make two-way binding on Blazor component
问题描述
我想创建自定义输入,所以我创建了此组件:
I want to create custom input, so I created this component:
MyInputComponent.razor
:
<div>
<input type="text" @bind="BindingValue" />
</div>
@code {
[Parameter]
public string BindingValue { get; set; }
}
然后使用:
<EditForm Model="model" OnValidSubmit="Submit">
<MyInputComponent BindingValue="model.Name" />
</EditForm>
@code {
User model = new User() { Name = "My Name" };
private void Submit()
{
// here I found model.Name = null;
}
}
当我调试MyInputComponent
时,我发现了输入的值.但是当我提交表单时,该值为null.
When I debug MyInputComponent
, I found the value as I have entered. But when I submit the form, the value is null.
该怎么做?
推荐答案
快速解答
引用 Blazor文档:
组件参数
绑定可以识别组件参数,其中@ bind- {property}可以跨组件绑定属性值.
Binding recognizes component parameters, where @bind-{property} can bind a property value across components.
对于您的页面:
<EditForm Model="model" OnValidSubmit="Submit">
<MyInputComponent @bind-BindingValue="model.Name" />
</EditForm>
子组件MyInputComponent
:
<div>
<InputText type="text" @bind-Value="@BindingValue" />
</div>
@code {
private string _value;
[Parameter]
public string BindingValue
{
get => _value;
set
{
if (_value == value ) return;
_value = value;
BindingValueChanged.InvokeAsync(value);
}
}
[Parameter]
public EventCallback<string> BindingValueChanged { get; set; }
}
通知
- 您应该通过
EventCallback<string> BindingValueChanged
引起子组件的绑定更改. - 我选择了
BindingValue
和BindingValueChanged
作为标识符,但是,您只能使用Value
和ValueChanged
.然后将是:<MyInputComponent @bind-Value="model.Name" />
- You should to raise binding changes from children component through
EventCallback<string> BindingValueChanged
. - I chose
BindingValue
andBindingValueChanged
as identifiers, but, you can use justValue
andValueChanged
. Then will be:<MyInputComponent @bind-Value="model.Name" />
已请参阅下面的选项2以获取干净的解决方案:
如果要将组件放入EditForm中并进行验证,或使用onchange事件执行其他操作,则应引发EditContext.NotifyFieldChanged
.您有2种选择可以做到.
If you want to put your component inside an EditForm and deal with validations, or take other actions using the onchange event, you should to raise EditContext.NotifyFieldChanged
. You have 2 options to do it.
您可以从CascadeParameter
获取EditContext
并手动调用NotifyFieldChanged
:
You can get EditContext
from CascadeParameter
and invoke NotifyFieldChanged
by hand:
[CascadingParameter] EditContext EditContext { get; set; } = default!;
[Parameter] public Expression<Func<string>>? ValueExpression { get; set; }
#endregion
#region bindedValue
[Parameter] public EventCallback<string> ValueChanged { get; set; }
private string _value { set; get; } = "";
[Parameter]
public string Value
{
get => _value;
set
{
if (_value == value) return;
_value = value;
ValueChanged.InvokeAsync(value);
var fieldIdentifier = FieldIdentifier.Create(ValueExpression);
EditContext.NotifyFieldChanged(fieldIdentifier);
}
}
选项2(推荐):通过从InputBase继承
您可以从InputBase<string>
继承而仅实现TryParseValueFromString
. InputBase
将为您完成工作,当您从 InputBase
,您有Value
,ValueChanged
,EditContext
等
Option 2 (recomended): Through inheritance from InputBase
You can inherit from InputBase<string>
and just implement TryParseValueFromString
. InputBase
will do the work for you,When you inherit from InputBase
you have Value
, ValueChanged
, EditContext
, etc.
protected override bool TryParseValueFromString(string? value, out string result, [NotNullWhen(false)] out string? validationErrorMessage)
{
result = value ?? "";
validationErrorMessage = null;
return true;
}
这篇关于如何在Blazor组件上进行双向绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!