本文介绍了如何制作使用 oninput 而不是 onchange 绑定的 EditForm Input?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
假设我想使用 EditForm
,但我希望每次用户输入控件时触发值绑定,而不仅仅是模糊.
举个例子,假设我想要一个 InputNumber
来做这个?我尝试使用不同的方法,例如 bind-Value:event="oninput"
,但没有成功.通过复制 InputNumber
的 AspNetCore 源代码并覆盖/重写一些东西,我终于能够或多或少地得到我想要的东西.
这是我的 InputNumber
,它实现了我的期望:
公共类 MyInputNumber: InputNumber{受保护的覆盖无效 BuildRenderTree(RenderTreeBuilder builder){builder.OpenElement(0, 输入");builder.AddAttribute(1, step", any");builder.AddMultipleAttributes(2, AdditionalAttributes);builder.AddAttribute(3, 类型", 数量");builder.AddAttribute(4, class", CssClass);builder.AddAttribute(5, value", FormatValue(CurrentValueAsString));builder.AddAttribute(6, oninput", EventCallback.Factory.CreateBinder(this, __value => CurrentValueAsString = __value, CurrentValueAsString));builder.CloseElement();}//复制自 AspNetCore - src/Components/Components/src/BindConverter.cs私有静态字符串 FormatValue(string value, CultureInfoculture = null) =>FormatStringValueCore(value,culture);//复制自 AspNetCore - src/Components/Components/src/BindConverter.cs私有静态字符串 FormatStringValueCore(字符串值,CultureInfo 文化){返回值;}}
注意oninput
";序列 6 中的项目从onchange
"更改为在基础 InputNumber
的 BuildRenderTree
方法中.我想知道如何:
- 查看
BuildRenderTree
的输出,以便我知道如何使用 Razor 和/或 - 只是大致知道什么样的 Razor 语法在未来会等同于这样做.
我从 AspNetCore 代码中的评论中收集到,这绝对不是做这类事情的首选方法,而 Razor 是首选方法.我已经通过订阅 EditContext
的 OnFieldChangedEvent
测试了这在 .NET Core 3 Preview 7 ASP.NET Core Hosted Blazor 中是否有效,并且可以通过这种方法看到这一点我得到了我正在寻找的不同行为.希望有更好的方法.
更新
包括一些关于问题的更多信息
@using BlazorAugust2019.Client.Components;@inherits BlazorFormsCode@page/blazorforms"<EditForm EditContext="EditContext"><div class="form-group row">
<div class="form-group row"><label for="summary";class=col-sm-2 col-form-label text-sm-right">总结:</label><div class="col-sm-4"><KlaInputText Id="summary";类=表单控制"@bind-Value=Model.Summary"></KlaInputText>
<div class="form-group row"><标签为=温度c"class=col-sm-2 col-form-label text-sm-right">温度°C</label><div class="col-sm-4"><KlaInputNumber Id=温度c";类=表单控制"@bind-Value=Model.TemperatureC"></KlaInputNumber>
<div class="form-group row">
</EditForm>
使用 BlazorAugust2019.Shared;使用 Microsoft.AspNetCore.Components;使用 Microsoft.AspNetCore.Components.Forms;使用系统;命名空间 BlazorAugust2019.Client.Pages.BlazorForms{公共类 BlazorFormsCode:ComponentBase{公共 EditContext EditContext;公共天气预报模型;公共 BlazorFormsCode(){模型 = 新的 WeatherForecast(){日期 = 日期时间.现在,摘要 = 测试",温度C = 21};EditContext = new EditContext(Model);EditContext.OnFieldChanged += EditContext_OnFieldChanged;}private void EditContext_OnFieldChanged(对象发送者,FieldChangedEventArgs e){Console.WriteLine($"EditContext_OnFieldChanged - {e.FieldIdentifier.FieldName}");}}}
我正在寻找的是EditContext_OnFieldChanged
";当我输入输入时触发的事件.当前示例有效,只是寻找更好的方法.
解决方案
对于任何想知道的人,您可以将 InputText
子类化以更改其呈现方式.例如,要使其使用 oninput
事件,创建 MyInputText.razor 包含:
@inherits Microsoft.AspNetCore.Components.Forms.InputText<input @attributes="@AdditionalAttributes";类=@CssClass";@bind="@CurrentValueAsString";@bind:event="oninput";/>
现在当你使用 它的行为就像 InputText
一样,只是它在每次击键时更新.
史蒂夫·桑德森
Suppose I want to use an EditForm
, but I want the value binding to trigger every time the user types into the control instead of just on blur.
Suppose, for the sake of an example, that I want an InputNumber<int>
that does this? I've tried using different means that are floating around such as bind-Value:event="oninput"
with no success. I was finally able to get more or less what I wanted by copying the AspNetCore source code for InputNumber
and overriding/rewriting a few things.
Here is my InputNumber<int>
which accomplishes what I'm hoping for:
public class MyInputNumber: InputNumber<int>
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddAttribute(1, "step", "any");
builder.AddMultipleAttributes(2, AdditionalAttributes);
builder.AddAttribute(3, "type", "number");
builder.AddAttribute(4, "class", CssClass);
builder.AddAttribute(5, "value", FormatValue(CurrentValueAsString));
builder.AddAttribute(6, "oninput", EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.CloseElement();
}
// Copied from AspNetCore - src/Components/Components/src/BindConverter.cs
private static string FormatValue(string value, CultureInfo culture = null) => FormatStringValueCore(value, culture);
// Copied from AspNetCore - src/Components/Components/src/BindConverter.cs
private static string FormatStringValueCore(string value, CultureInfo culture)
{
return value;
}
}
note the "oninput
" in the sequence 6 item was changed from "onchange
" in the base InputNumber
's BuildRenderTree
method. I'd like to know how to:
- see the output of
BuildRenderTree
, so that I can know how to do this with Razor and/or - just kind of know in general what sort of Razor syntax would be equivalent to doing this in the future.
I've gathered from comments in the AspNetCore code that this is definitely not the preferred way of doing this sort of thing, with Razor being the preferred approach. I've tested that this works in .NET Core 3 Preview 7 ASP.NET Core Hosted Blazor by subscribing to the EditContext
's OnFieldChangedEvent
, and can see that with this approach I get the different behavior that I'm looking for. Hopefully there is a better way.
Update
Including some more information about the problem
@using BlazorAugust2019.Client.Components;
@inherits BlazorFormsCode
@page "/blazorforms"
<EditForm EditContext="EditContext">
<div class="form-group row">
<label for="date" class="col-sm-2 col-form-label text-sm-right">Date: </label>
<div class="col-sm-4">
<KlaInputDate Id="date" Class="form-control" @bind-Value="Model.Date"></KlaInputDate>
</div>
</div>
<div class="form-group row">
<label for="summary" class="col-sm-2 col-form-label text-sm-right">Summary: </label>
<div class="col-sm-4">
<KlaInputText Id="summary" Class="form-control" @bind-Value="Model.Summary"></KlaInputText>
</div>
</div>
<div class="form-group row">
<label for="temperaturec" class="col-sm-2 col-form-label text-sm-right">Temperature °C</label>
<div class="col-sm-4">
<KlaInputNumber Id="temperaturec" Class="form-control" @bind-Value="Model.TemperatureC"></KlaInputNumber>
</div>
</div>
<div class="form-group row">
<label for="temperaturef" class="col-sm-2 col-form-label text-sm-right">Temperature °F</label>
<div class="col-sm-4">
<input type="text" id="temperaturef" class="form-control" value="@Model.TemperatureF" readonly />
</div>
</div>
</EditForm>
using BlazorAugust2019.Shared;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System;
namespace BlazorAugust2019.Client.Pages.BlazorForms
{
public class BlazorFormsCode : ComponentBase
{
public EditContext EditContext;
public WeatherForecast Model;
public BlazorFormsCode()
{
Model = new WeatherForecast()
{
Date = DateTime.Now,
Summary = "Test",
TemperatureC = 21
};
EditContext = new EditContext(Model);
EditContext.OnFieldChanged += EditContext_OnFieldChanged;
}
private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
{
Console.WriteLine($"EditContext_OnFieldChanged - {e.FieldIdentifier.FieldName}");
}
}
}
What I'm looking for is the "EditContext_OnFieldChanged
" event to fire when I type into the inputs. The current example works, just looking for a better way.
解决方案
For anyone wondering, you can subclass InputText
to change how it renders. For example, to make it use the oninput
event, create MyInputText.razor containing:
@inherits Microsoft.AspNetCore.Components.Forms.InputText
<input @attributes="@AdditionalAttributes" class="@CssClass" @bind="@CurrentValueAsString" @bind:event="oninput" />
Now when you use <MyInputText @bind-Value="@someval" />
it will behave just like InputText
except it updates on each keystroke.
SteveSanderson
这篇关于如何制作使用 oninput 而不是 onchange 绑定的 EditForm Input?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
08-11 22:02