如何在继承的组件中自动设置事件回调?
How to set event callback automatically in inherited component?
目前我有:
<InputText @oninput="@SomeHandler" />
现在我需要使用仅 class 的组件从 InputText
继承,我想在这个新组件中自动设置事件处理程序,所以我会像这样使用新组件:
<CustomInputText />
如何在自定义组件中设置事件处理程序?
<InputText @oninput="@SomeHandler" />
@oninput
是一个编译器属性指令,旨在与 Html 标记一起使用,而不是与组件一起使用。 InputText
是组件标签,而不是 Html 标签。过去,此类应用程序会被忽略或引发编译错误;然而,目前,编译器属性指令可能会由编译器静默添加,但通常会导致难以辨别的细微问题。你应该尽量避免这种情况。
如果你想子class InputText
并像这样使用它:<CustomInputText />
,
您只需从 InputText
派生,如下所示:
public partial class CustomInputText : InputText
{
// Add here the internal work...
}
并在EditForm上使用(注意:必须嵌入在EditForm组件中),像这样:
<EditForm>
<CustomInputText />
</EditForm>
I would like to set òninput=SomeHandler (or an equivalent) directly in the ctor or OnAfterRender of the custom component
重要的是要了解虽然组件是 C# class,但它是 class 的特例,您不应尝试将其用作普通 C# class。例如,你不应该像这样实例化一个组件:
CustomInputText MyCustomInputText = new CustomInputText();
然后调用它的方法和属性,就好像它是一个普通的 C# class 对象一样。您应该像这样将其实例化为组件元素:
<CustomInputText @bind-Value="myValue" />
这是因为组件模型的渲染引擎正确地进行了实例化...现在,如果您将组件实例化为一个普通的 C# class 对象,您将跳过对渲染引擎,在最好的情况下会使您的组件无用。我告诉你这是因为你应该忘记构造函数的概念。没有构造函数...
Blazor 具有生命周期方法,您应该在初始化组件时重写这些方法。
下面是描述如何子class 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; }
}
}
目前我有:
<InputText @oninput="@SomeHandler" />
现在我需要使用仅 class 的组件从 InputText
继承,我想在这个新组件中自动设置事件处理程序,所以我会像这样使用新组件:
<CustomInputText />
如何在自定义组件中设置事件处理程序?
<InputText @oninput="@SomeHandler" />
@oninput
是一个编译器属性指令,旨在与 Html 标记一起使用,而不是与组件一起使用。 InputText
是组件标签,而不是 Html 标签。过去,此类应用程序会被忽略或引发编译错误;然而,目前,编译器属性指令可能会由编译器静默添加,但通常会导致难以辨别的细微问题。你应该尽量避免这种情况。
如果你想子class InputText
并像这样使用它:<CustomInputText />
,
您只需从 InputText
派生,如下所示:
public partial class CustomInputText : InputText
{
// Add here the internal work...
}
并在EditForm上使用(注意:必须嵌入在EditForm组件中),像这样:
<EditForm>
<CustomInputText />
</EditForm>
I would like to set òninput=SomeHandler (or an equivalent) directly in the ctor or OnAfterRender of the custom component
重要的是要了解虽然组件是 C# class,但它是 class 的特例,您不应尝试将其用作普通 C# class。例如,你不应该像这样实例化一个组件:
CustomInputText MyCustomInputText = new CustomInputText();
然后调用它的方法和属性,就好像它是一个普通的 C# class 对象一样。您应该像这样将其实例化为组件元素:
<CustomInputText @bind-Value="myValue" />
这是因为组件模型的渲染引擎正确地进行了实例化...现在,如果您将组件实例化为一个普通的 C# class 对象,您将跳过对渲染引擎,在最好的情况下会使您的组件无用。我告诉你这是因为你应该忘记构造函数的概念。没有构造函数...
Blazor 具有生命周期方法,您应该在初始化组件时重写这些方法。
下面是描述如何子class 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; }
}
}