简体   繁体   English

Blazor 绑定值:输入事件

[英]Blazor bind-value:event oninput

I am trying to trigger the model validation in Blazor by using EditForm .我正在尝试使用EditForm在 Blazor 中触发 model 验证。

For some reason, the oninput event doesn't seem to be called if using the InputText , but it works using a simple input element.出于某种原因,如果使用InputText似乎不会调用oninput事件,但它可以使用简单的input元素工作。

Have I missed something?我错过了什么吗?

Here is an HTML sample:这是一个 HTML 示例:

<EditForm Model="@Model" OnValidSubmit="@OnValidSubmit" id="authorize">
    <h1 class="mb-3">
       <span class="d-block">Authorize</span>
    </h1>
    <DataAnnotationsValidator />
    <div class="form-group">
        <label class="sr-only" for="AuthorizeUsername">Username</label>
        <div class="input-group mb-2">
            <div class="input-group-prepend">
                <div class="input-group-text"><i class="fas fa-user"></i></div>
            </div>
            <InputText type="text" class="form-control" id="AuthorizeUsername" placeholder="Username" @bind-value="@Model.Username" @bind-value:event="oninput" />
        </div>
    </div>
    <div class="form-group">
        <label class="sr-only" for="AuthorizePassword">Password</label>
        <div class="input-group mb-2">
            <div class="input-group-prepend">
                <div class="input-group-text"><i class="fas fa-asterisk"></i></div>
            </div>
            <InputText type="password" class="form-control" id="AuthorizePassword" placeholder="Password" @bind-value="@Model.Password" @bind-value:event="oninput" />
        </div>
    </div>
    <div class="form-group">
        <ValidationSummary />
        <button type="submit" class="btn btn-outline-primary"><i class="fas fa-sign-in-alt mr-1"></i> Login</button>
    </div>
</EditForm>

If you need this for validation, see the answer for this:如果您需要此进行验证,请参阅此答案:

How to make an EditForm Input that binds using oninput rather than onchange 如何制作使用 oninput 而不是 onchange 绑定的 EditForm Input

Original Answer原答案

TLDR: Blazor Input components do not support this out of the box. TLDR:Blazor 输入组件不支持开箱即用。 You need to roll your own by extending InputBase, and your Razor markup for your new component will put the input event binding directly on the input element.您需要通过扩展 InputBase 来推出自己的产品,新组件的 Razor 标记会将输入事件绑定直接放在输入元素上。

It would be nice if this came as an out-of-the-box option, but at least there is a way to do it that isn't terrible.如果这是一个开箱即用的选项,那就太好了,但至少有一种方法可以做到这一点并不可怕。 Be aware though that this quickly gets more complicated for more complicated input types.但请注意,对于更复杂的输入类型,这会很快变得更加复杂。 If you want your own InputBase<DateTime> derived class, for example, you need to be prepared to correctly handle DateTime formatting in the binding events.例如,如果您想要自己的InputBase<DateTime>派生类,则需要准备好正确处理绑定事件中的 DateTime 格式。

The markup for your own version of InputText , lets call it MyInputTextCode that extends InputBase<string> would look something exactly like this:您自己的InputText版本的标记,我们称之为MyInputTextCode扩展InputBase<string>看起来完全像这样:

@inherits MyInputTextCode;

<input type="text" id="@Id" class="@Class" @bind-value="CurrentValueAsString" @bind-value:event="oninput" />

where MyInputTextCode is the class name of your implementation of InputBase<string>其中MyInputTextCodeInputBase<string>实现的类名

The usage would essentially be the same as InputText , but you would instead use the file name (witout the extension) of your .razor markup instead of InputText .用法基本上与InputText相同,但您可以使用 .razor 标记的文件名(没有扩展名)而不是InputText

UPDATE 4-30-2020 I no longer recommend deriving from InputBase in your code-behind, instead you can simply @inherits an existing form component class such as InputText and override the markup in your .razor file. 2020 年 4 月 30 日更新我不再建议在您的代码隐藏中从 InputBase 派生,相反您可以简单地@inherits现有表单组件类(例如 InputText)并覆盖 .razor 文件中的标记。 If this isn't clear please comment on this answer and I'll elaborate further in this update.如果这不清楚,请对此答案发表评论,我将在此更新中进一步详细说明。

It works on a simple input because you are binding to the html attribute "value".它适用于简单的输入,因为您绑定到 html 属性“值”。

InputText is a C# class. InputText 是一个 C# 类。 The property name you need to bind to is Value with a capital V.您需要绑定的属性名称是带有大写 V 的Value

Change all @bind-value occurrences to @bind-Value and it should work.将所有出现的@bind-value更改为@bind-Value并且它应该可以工作。

As a workaround, I found that changing from Blazor components such as InputTextArea to plain HTML textarea tag and leveraging the binding on them can fix the problem:作为一种解决方法,我发现将诸如InputTextArea Blazor 组件更改为纯 HTML textarea标记并利用它们上的绑定可以解决问题:

<textarea @bind="@ViewModel.TargetProperty" @bind:event="oninput"/>

or for input tags:input标签:

<input type="email" @bind="@ViewModel.Email" @bind:event="oninput"/>

Works in .Net 5 Blazor WASM at least.至少适用于 .Net 5 Blazor WASM。

I found this answer and a workaround:我找到了这个答案和解决方法:

https://github.com/dotnet/aspnetcore/issues/12657 https://github.com/dotnet/aspnetcore/issues/12657

Basically @bind-Value:event="oninput" is not supported on <InputText> but you can easily derive a new control from 'InputText' which does update on input. <InputText>基本上不支持@bind-Value:event="oninput"但您可以轻松地从'InputText' 派生一个新控件,该控件会在输入时更新。

Quoted from the original github post for reference:引用自原 github 帖子供参考:

Create MyInputText.razor containing:创建 MyInputText.razor 包含:

@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.现在,当您使用<MyInputText @bind-Value="@someval" />时,它的行为就像 InputText 一样,只是它会在每次击键时更新。

A similar technique as Amir Mahdi said in another answer, I just wanted to point out that this is explained on the official docs also now for As.netcore 6.0 and 7.0.与 Amir Mahdi 在另一个答案中所说的类似技术,我只是想指出,现在在 As.netcore 6.0 和 7.0 的官方文档中也对此进行了解释。 https://learn.microsoft.com/en-us/as.net/core/blazor/forms-and-input-components?view=as.netcore-6.0 https://learn.microsoft.com/en-us/as.net/core/blazor/forms-and-input-components?view=as.netcore-6.0

See the heading ' InputText based on the input event '.请参阅标题“基于输入事件的 InputText ”。

Here is how they suggest to use it, I however see the value of also being in charge of which client side event will trigger update (usually it will be 'oninput', but maybe you want to use another client side event?)这是他们建议如何使用它,但是我看到了还负责哪个客户端事件将触发更新的价值(通常是“oninput”,但也许您想使用另一个客户端事件?)

Just define a new reusable component like CustomInputText.razor with the following content:只需使用以下内容定义一个新的可重用组件,如 CustomInputText.razor:

@inherits InputText

    <input @attributes="AdditionalAttributes"
           class="@CssClass"
           @bind="CurrentValueAsString"
           @bind:event="@UpdateSourceTrigger" />
    
    
    @code {
        [Parameter]
        public string UpdateSourceTrigger { get; set; } = "oninput";
     }

To use it inside a razor view just use it like a regular InputText field, the only thing that is adjusted is that it automatically binds to the 'oninput' client side event.要在 razor 视图中使用它,只需像常规 InputText 字段一样使用它,唯一需要调整的是它会自动绑定到“oninput”客户端事件。 You can adjust which event also is bound to do an update.您可以调整哪些事件也必然会进行更新。 This can both be positive sine you see your changes on key stroke and negative in case updating the backend from the UI is slow, as every keyboard stroke will write data back to the bound property, possibly trigger additional processing too if you have bound it to an 'autosave' feature or similar.这既可以是积极的正弦,因为您看到您对击键的更改,也可以是消极的,以防从 UI 更新后端很慢,因为每次键盘击打都会将数据写回绑定的属性,如果您将其绑定到,也可能触发额外的处理“自动保存”功能或类似功能。

I used the name UpdateSourceTrigger here for the property trigger event - as this reminds me a bit how we adjusted things in WPF when to write back to two way bound fields !我在这里使用名称 UpdateSourceTrigger 作为属性触发事件 - 因为这让我想起了我们如何调整 WPF 中的内容,何时写回双向绑定字段!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM