1

所以我有点困惑,我认为某些提交逻辑在 Blazor Server 中是如何工作的(可能与 Blazor WebAssembly 相同)。

我有一个带有字段和提交按钮(提交类型)的 EditForm:

    <EditForm EditContext="@_editContext" OnValidSubmit="@HandleValidSubmit">
        <DataAnnotationsValidator />
        <ValidationSummary />

        <label for="firstName" class="form-label">First Name</label>
        <InputText class="form-control" @bind-Value="_formModel.FirstName" />
        <button type="submit" class="btn btn-primary">New Person</button>

    </EditForm>


    @code {
    
    private void HandleValidSubmit()
    {
       System.Diagnostics.Debug.WriteLine("SUBMIT!");
    }
    
    private class FormModel
    {
        [Required(AllowEmptyStrings = false, ErrorMessage = "Provide a first name")]
        public string FirstName{ get; set; }

    }
    
}

在浏览器中,我执行以下操作:

  1. 提供将根据我的评估为无效的输入,FormModel并且DataAnnotationsValidator我被告知只需单击一个按钮。这是意料之中的。
  2. 我更正了名字文本输入的值,并且它仍然在浏览器中具有焦点,我单击Submit
  3. 所发生的一切是 DataValidation 似乎已经运行(很酷,这总是好的),但是单击Submit按钮似乎并没有触发我运行 OnValidSubmit 的 C# 代码。(正如你在我的例子中看到的,我用Debug.WriteLine

有没有办法避免这种情况,同时使用 OnSubmit/OnInvalidSubmit/OnValidSubmit 和 type="submit" 的按钮保持 EditForm?

(我读到在 Blazor 和 State 更新中使用类型按钮与类型按钮时存在一些差异submit......button不知道这是否是一个因素)

从用户的角度来看,他们按两次按钮执行一个操作。这当然会让人觉得有点奇怪或混乱。

根据我的测试,这似乎是涉及 DataAnnotationsValidator 的情况,这部分是有道理的,直到需要在客户端上按下两个按钮才能实际点击我的 C# 代码。(即我知道焦点改变时正在发生数据验证)

我觉得我部分误解了某些东西,并且部分遗漏了我的表单中的一些额外代码或设置以避免这种情况。

有没有办法做我想做的事情,同时保持DataAnnotationsValidator?

提前感谢您的帮助!

4

1 回答 1

0

我认为发生的事情是,当您“单击”按钮(显示验证消息)时,首先发生的是输入控件失去焦点。这会导致验证事件 - 数据条目通过验证、ValidationSummary更新并消失。渲染事件将按钮向上分流,因此当浏览器应用点击事件时,它位于屏幕的空白位上,而不是按钮上。在下面的测试代码中,我在上面添加了一个提交按钮,ValidationSummary因为它不会移动。它发生得太快,你错过了!

解决此问题的一种方法是更改​​输入的行为以验证数据输入,而不是失去焦点。

这是一个自定义控件InputText

@namespace MyNameSpace
@inherits InputText

<input type="text" value="@this.CurrentValue" @oninput="OnInput" @ref="Element" />

@code{

    public ElementReference? Element { get; set; }

    private void OnInput(ChangeEventArgs e)
    => this.CurrentValueAsString = e.Value.ToString();
}

它与原始版本之间的唯一区别在于响应事件现在设置为“oninput”而不是“onchange”。

测试页面如下所示。显示控件的两个版本,因此您可以看到不同的行为。

@page "/Test2"
<EditForm EditContext="@_editContext" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="HandleInValidSubmit">

    <DataAnnotationsValidator />

    <div class=" m-2 p-2">
        <button type="submit" class="btn btn-primary">New Person</button>
    </div>

    <ValidationSummary />

    <label class="form-label">First Name (Only Updates on Exit)</label>
    <InputText class="form-control" @bind-Value="this._formModel.FirstName"></InputText>

    <label class="form-label">First Name (Updates on Typing)</label>
    <InputTextOnInput class="form-control" @bind-Value="this._formModel.FirstName"></InputTextOnInput>

    <button type="submit" class="btn btn-primary">New Person</button>

</EditForm>

<div class="m-3 p-3">@_submitType</div>

@code {
    private EditContext? _editContext;
    private FormModel _formModel;
    private string _submitType;

    private void HandleValidSubmit()
    {
        _submitType = "VALID SUBMIT!";
        System.Diagnostics.Debug.WriteLine("VALID SUBMIT!");
    }

    private void HandleInValidSubmit()
    {
        _submitType = "INVALID SUBMIT!";
        System.Diagnostics.Debug.WriteLine("INVALID SUBMIT!");
    }

    private class FormModel
    {
        [Required(AllowEmptyStrings = false, ErrorMessage = "Provide a first name")]
        public string FirstName { get; set; }

    }

    protected override Task OnInitializedAsync()
    {
        _formModel = new FormModel();
        _editContext = new EditContext(_formModel);
        return base.OnInitializedAsync();
    }

}

这是输入控件源代码的链接

于 2021-07-27T10:22:54.217 回答