<InputText @oninput="@SomeHandler" />
@oninput 是一个编译器属性指令,旨在与 Html 标记一起使用,而不是与组件一起使用。 InputText 是一个组件标签,而不是 Html 标签。过去,此类应用程序被忽略或引发编译错误;然而,目前,编译器可能会默默地添加编译器属性指令,但通常可能会导致难以辨别的细微问题。你应该尽量避免这种情况。
如果你想继承 InputText 并像这样使用它:<CustomInputText />,
您只需从InputText 派生,如下所示:
public partial class CustomInputText : InputText
{
// Add here the internal work...
}
并在 EditForm 上使用(注意:必须嵌入到 EditForm 组件中),像这样:
<EditForm>
<CustomInputText />
</EditForm>
我想直接在自定义组件的 ctor 或 OnAfterRender 中设置 òninput=SomeHandler(或等效项)
重要的是要了解,虽然组件是 C# 类,但它是类的特例,您不应该尝试将其用作普通 C# 类。例如,你不应该像这样实例化一个组件:
CustomInputText MyCustomInputText = new CustomInputText();
然后调用它的方法和属性,就好像它是一个普通的 C# 类对象一样。您应该像这样将它实例化为组件元素:
<CustomInputText @bind-Value="myValue" />
这是因为组件模型的渲染引擎正确地进行了实例化...现在,如果您将组件实例化为就好像它是一个普通的 C# 类对象一样,您将跳过渲染引擎的处理,其中最好的情况会使您的组件无用。我告诉你这个是因为你应该忘记构造函数的 ide。没有构造函数...
Blazor 具有生命周期方法,您应该在初始化组件时覆盖这些方法。
下面是一个代码示例,描述了如何对 InputText 组件进行子类化...复制测试并学习:
NumericInputText.razor.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Web;
public partial class NumericInputText : InputText
{
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
__builder.OpenElement(0, "input");
__builder.AddAttribute(1, "type", "number");
__builder.AddMultipleAttributes(2, AdditionalAttributes);
__builder.AddAttribute(3, "class", CssClass);
__builder.AddAttribute(4, "value", CurrentValueAsString);
__builder.AddEventPreventDefaultAttribute(5, "onkeypress", true);
__builder.AddAttribute(6, "onblur", Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.FocusEventArgs>(this, OnBlurEventHandler));
__builder.AddAttribute(7, "onkeydown", Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.KeyboardEventArgs>(this, OnKeyDown));
__builder.AddAttribute(8, "oninput", Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.ChangeEventArgs>(this, OnInput));
__builder.CloseElement();
}
protected override void OnInitialized()
{
CurrentValueAsString = "0";
}
private void OnInput(ChangeEventArgs args)
{
if (args.Value.ToString() == "")
{
CurrentValueAsString = "0";
}
else
{
CurrentValueAsString = args.Value.ToString();
}
}
private void OnKeyDown(KeyboardEventArgs e)
{
if (e.Key == "Backspace" && CurrentValueAsString.Length == 1)
{
CurrentValueAsString = "";
}
if (e.Key == "+")
{
var value = int.Parse(CurrentValueAsString);
value++;
CurrentValueAsString = value.ToString();
}
else if (e.Key == "-")
{
var value = int.Parse(CurrentValueAsString);
value--;
CurrentValueAsString = value.ToString();
}
if (Regex.IsMatch(e.Key, "[0-9]"))
{
CurrentValueAsString += int.Parse($"{e.Key}").ToString();
}
}
protected void OnBlurEventHandler(Microsoft.AspNetCore.Components.Web.FocusEventArgs e)
{
if (string.IsNullOrWhiteSpace(CurrentValueAsString))
{
CurrentValueAsString = "0";
}
}
}
用法
<EditForm Model="@Model" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">
<div class="alert @StatusClass">@StatusMessage</div>
<DataAnnotationsValidator />
<ValidationSummary />
<div class="form-group">
<label for="name">Name: </label>
<NumericInputText Id="name" Class="form-control" @bind-Value="@Model.NumberSelection" />
<ValidationMessage For="@(() => Model.NumberSelection)" />
</div>
<button type="submit">Ok</button>
</EditForm>
@code {
private string StatusMessage;
private string StatusClass;
private Comment Model = new Comment();
protected void HandleValidSubmit()
{
StatusClass = "alert-info";
StatusMessage = DateTime.Now + " Handle valid submit";
}
protected void HandleInvalidSubmit()
{
StatusClass = "alert-danger";
StatusMessage = DateTime.Now + " Handle invalid submit";
}
public class Comment
{
public string NumberSelection { get; set; }
}
}