我想绑定到该值并在更改后触发方法 CalculateStandardDimensions。我尝试了几种不同的语法组合,但我仍然缺少一些东西来完成这项工作。 离开输入不会执行方法。
如何绑定值并在值改变时调用方法?
<input class="form-control form-control-sm" type="number" step="any" @bind-value:event="onchange=CalculateStandardDimensions()" @bind-value="Cyclone.CycloneSize" />
我在代码部分有这个。
private void CalculateStandardDimensions()
{
// Do Stuff Here
}
答案 0 :(得分:4)
这似乎是一项简单的任务,但您需要考虑一些事项。
在 Blazor 中,从输入返回模型的通道是通过事件处理的。如果您使用 @bind-
语法,编译器会为您构建处理程序。因此,您无法(轻松)同时更新模型值并执行另一个处理程序。
但是,有一些方便的方法可以实现您想要的。但它们有缺点。根据您的情况,您需要决定什么是最好的。
使用不同的事件
@page "/DifferentEvents"
<input class="form-control form-control-sm" type="number" step="any"
@bind-value:event="onchange" @oninput="CalculateStandardDimensions" @bind-value="Cyclone.CycloneSize" />
@code
{
public class Cyclon
{
public Int32 CycloneSize { get; set; } = 10;
}
public Cyclon Cyclone = new Cyclon();
private void CalculateStandardDimensions(ChangeEventArgs args)
{
// Do Stuff Here
}
}
在这种情况下,您的模型将在输入失去焦点 (onchange) 时更新,但每次输入更改时都会执行您的方法 CalculateStandardDimensions
。新值可通过 ChangeEventArgs args
访问。
缺点:潜在的不一致,因为模型不知道更新,但你用它来做其他事情。
使用具有双向绑定的中介属性
@page "/IntermediatePropertyWithBinding"
<input class="form-control form-control-sm" type="number" step="any" @bind-value:event="onInput" @bind-value="Size" />
@code
{
public class Cyclon
{
public Int32 CycloneSize { get; set; } = 10;
}
public Cyclon Cyclone = new Cyclon();
private Int32 _size;
public Int32 Size
{
get => _size;
set
{
_size = value;
CalculateStandardDimensions();
Cyclone.CycloneSize = value;
}
}
private void CalculateStandardDimensions()
{
// Do Stuff Here
}
}
通过将字段 _size
与属性 Size
一起引入,您可以绑定,Size
的 setter 将调用 CalculateStandardDimensions()
。根据绑定 onInput
或 onChange
的事件,您可以控制回写的时间。
您可以完全控制绑定,避免了不一致。但是,您引入了新的字段和属性。需要为您希望具有此类行为的每个属性执行此操作。
使用没有绑定的中介属性
@page "/IntermediatePropertyWithoutBinding"
<input class="form-control form-control-sm" type="number" step="any" value="@_size" @oninput="ValueChanged" />
@code
{
public class Cyclon
{
public Int32 CycloneSize { get; set; } = 10;
}
public Cyclon Cyclone = new Cyclon();
private Int32 _size;
private void ValueChanged(ChangeEventArgs args)
{
_size = Convert.ToInt32((String)args.Value);
Cyclone.CycloneSize = _size;
CalculateStandardDimensions();
}
private void CalculateStandardDimensions()
{
// Do Stuff Here
}
}
我们摆脱了绑定和属性。输入字段的值是直接设置的。 (没有@bind-value
)。在事件处理程序中,我们设置更新值、写回模型并执行 CalculateStandardDimensions()
方法。
我们失去了双向绑定的所有功能,但不再需要属性。
EditContext OnFieldChanged 事件
@page "/WithEditContext"
@implements IDisposable
<EditForm EditContext="_editContext">
<InputNumber class="form-control form-control-sm" type="number" step="any" @bind-Value:event="onchange" @bind-Value="Cyclone.CycloneSize" />
</EditForm>
@code
{
public class Cyclon
{
public Int32 CycloneSize { get; set; } = 10;
}
private EditContext _editContext;
public Cyclon Cyclone = new Cyclon();
protected override void OnInitialized()
{
base.OnInitialized();
_editContext = new EditContext(Cyclone);
_editContext.OnFieldChanged += OnFormUpdated;
}
public void Dispose()
{
_editContext.OnFieldChanged -= OnFormUpdated;
}
private void OnFormUpdated(Object sender, FieldChangedEventArgs args)
{
if(args.FieldIdentifier.FieldName == nameof(Cyclon.CycloneSize))
{
CalculateStandardDimensions();
}
}
private void CalculateStandardDimensions()
{
}
}
EditContext
是在使用带有 Model
属性的 EditForm 时隐式创建的,它具有在将值写回模型时触发的事件。我们通过显式创建 EditContext 并订阅事件来使用它。不要忘记稍后删除处理程序。这就是我们实施 IDisposable
的原因。事件处理程序本身检查该字段是否是我们期望的字段并执行方法 CalculateStandardDimensions()
。 HTML input 元素需要替换为 InputNumber
才能让绑定生效。
这种方法具有很大的灵活性,但也带来了更多的复杂性。但是,您可以将其与 InputText
或 InputSelect
等每个输入组件一起使用。