<EditForm autocomplete="off" class="contex card-body" Model="Input" OnValidSubmit="OnSaveChangesAsync">
<!-- all fields and validations -->
<EditButton>Save changes</EditButton>
</EditForm>
我有这样的形式。它执行许多验证。然后保存更改。几乎一切正常。
问题是第一次单击该按钮不执行任何操作(似乎使该按钮处于活动状态),第二次单击实际上提交了表单。当然,它可能集中在表单元素上,但这不应阻止按钮正常工作。
如何使按钮在单击时起作用,而不是双击/第二次单击?
编辑:编辑按钮源:
EditButton.razor:
@namespace Woof.Blazor.Components
<button type="submit" class="@CssClass" @attributes="AdditionalAttributes">@ChildContent</button>
EditButton.razor.cs:
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Components;
namespace Woof.Blazor.Components {
public partial class EditButton {
[Parameter] public RenderFragment ChildContent { get; set; }
/// <summary>
/// Gets or sets a collection of additional attributes that will be applied to the created element.
/// </summary>
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object> AdditionalAttributes { get; set; }
string CssClass {
get {
const string defaultClass = "btn btn-primary baseline";
if (AdditionalAttributes != null &&
AdditionalAttributes.TryGetValue("class", out var @class) &&
!string.IsNullOrEmpty(Convert.ToString(@class, CultureInfo.InvariantCulture))) {
return $"{defaultClass} {@class} ";
} else return defaultClass;
}
}
}
}
让我重新说明这个问题,以使其更清楚:我怀疑按钮的第一次单击只是赋予按钮焦点(将焦点从输入元素中移出),第二次单击被注册为“提交”动作。我要跳过聚焦部分,然后单击以致电OnValidSubmit
EventCallback
。同样重要的是,当触摸按钮时,它可以在平板电脑上以这种方式工作。一键即可保存更改。意外单击按钮的后果几乎没有。如果未对表单进行任何更改,我的代码将跳过更新。如果进行了无效的更改-验证将不允许OnValidSubmit
被触发。进行有效更改后,但未全部输入-用户仍然可以重新编辑已保存的项目。另一方面,如果用户忘记保存更改,这将导致表单可能存在错误,而不是被更正,而用户甚至不知道发生了什么。用户可以关闭浏览器,平板设备可以锁定屏幕。几次我个人使用银行应用程序犯了类似的错误:我以为我已汇款并等待发货,却发现我尚未确认转账,而商店仍在等待我的付款。我称它为主要的烦恼,当我遇到它时我不喜欢它,所以我不希望它发生在我的应用程序的用户身上。
该答案的目的是反驳问题作者自己接受的答案的有效性。
这是OP发布的问题代码。
@namespace Woof.Blazor.Components
<button type="submit" class="@CssClass" @attributes="AdditionalAttributes">@ChildContent</button>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Globalization;
using Microsoft.AspNetCore.Components;
namespace Woof.Blazor.Components
{
public partial class EditButton
{
[Parameter] public RenderFragment ChildContent { get; set; }
/// <summary>
/// Gets or sets a collection of additional attributes that will be applied to the created element.
/// </summary>
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object> AdditionalAttributes { get; set; }
string CssClass
{
get
{
const string defaultClass = "btn btn-primary baseline";
if (AdditionalAttributes != null &&
AdditionalAttributes.TryGetValue("class", out var @class) &&
!string.IsNullOrEmpty(Convert.ToString(@class, CultureInfo.InvariantCulture)))
{
return $"{defaultClass} {@class} ";
}
else return defaultClass;
}
}
}
}
以下是我用于测试目的的代码。将其复制到“索引”页面并运行该应用程序...请注意,我正在使用Blazor Server应用程序。
@page "/"
@using System
@using System.Collections.Generic
@using System.Linq
@using System.Threading.Tasks
@using System.ComponentModel.DataAnnotations
@using Woof.Blazor.Components
<EditForm Model="@Model" OnValidSubmit="@HandleValidSubmit"
OnInvalidSubmit="@HandleInvalidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="form-group">
<label for="name">Name: </label>
<InputText autocomplete="off" Id="name" Class="form-control"
@bind-Value="@Model.Name"></InputText>
<ValidationMessage For="@(() => Model.Name)" />
</div>
<div class="form-group">
<label for="body">Text: </label>
<InputTextArea autocomplete="off" Id="body" Class="form-control"
@bind-Value="@Model.Text"></InputTextArea>
<ValidationMessage For="@(() => Model.Text)" />
</div>
<EditButton>Save changes</EditButton>
</EditForm>
@code
{
private Comment Model = new Comment();
protected void HandleValidSubmit()
{
Console.WriteLine("Handle valid submit");
}
protected void HandleInvalidSubmit()
{
Console.WriteLine("Handle Invalid Submit");
}
public class Comment
{
[Required]
[MaxLength(10)]
public string Name { get; set; }
[Required]
public string Text { get; set; }
}
}
这表明您的主张
接下来的问题是:如果另一个编辑组件具有焦点,则该按钮必须首先获得焦点,然后才能单击它
不仅是错误的,而且还清楚地揭示了您如何“选择”忽略Web和其他地方的UI元素的行为。
在“名称”字段中键入一个名称,然后用鼠标指针单击“保存更改”按钮。DataAnnotations验证立即响应并显示以下消息:“必须输入文本字段。”
转到“输出”窗口,然后看到消息:“处理无效的提交”
返回网页,并在“文本字段”中输入一些文本,然后用鼠标指针单击“保存更改”按钮。
红色文本消息消失。
现在转到输出窗口,看到没有消息发出,这尤其意味着click事件从未被触发。这导致您形成错误的断言,即“浏览器本身不将点击视为点击。” 但是,可惜,从来没有单击“保存更改”按钮。您的解释毫无意义,也没有任何价值可解释这里发生的事情...
当您将鼠标指针指向“保存更改”按钮并尝试单击它时,“文本”字段将失去焦点,其结果是DataAnnotations代码删除了红色消息,并随后重新呈现了所涉及的组件。这样做的速度使您无法产生将在重新渲染之前执行的单击。该代码以光速执行,但是即使您足够快(光速,右)在松开焦点到开始重新渲染之间的间隔中插入单击,该代码也会以给定顺序执行。无论如何,仍然存在重新渲染组件的事实,并且您没有成功引发或发出click事件,因为“保存更改”按钮没有焦点。正如我在测试1中所展示的,不需要重点。
如您所见,红色消息已被删除,也就是说,已经重新渲染了组件。4.现在,当焦点位于“名称”字段中时,用鼠标指针单击“保存更改”按钮。5.转到“输出”窗口,然后看到消息:“处理有效的提交”
添加以下onmouseover =“ document.getElementById('name')。focus();” 到EditButton.razor文件中的button元素。这代替了在接受的答案中用作解决方案的onmouseover =“ this.focus()”。
在“名称”字段中键入一个名称,然后用鼠标指针单击“保存更改”按钮。DataAnnotations验证立即响应并显示以下消息:“必须输入文本字段。”
转到“输出”窗口,然后看到消息:“处理无效的提交”
返回网页,然后在“文本字段”中输入一些文本。现在,当您向“保存更改”按钮的方向移动鼠标时,将触发mouseover事件,并且焦点将设置为“名称”字段。
现在,当焦点位于“名称”字段中时,用鼠标指针单击“保存更改”按钮。
转到“输出”窗口,然后看到消息:“处理有效的提交”
请注意,行为是通过将onmouseover =“ this.focus()”与onmouseover =“ document.getElementById('name')。focus();”交换而引起的)完全相同显然,您不必为了单击而设置“保存更改”按钮的焦点。只有在代码相关的DataAnnotations刷新了组件之后,才可以单击。
总结:无论您在回答中说的是什么,以及评论都是毫无根据,错误和误导的。我同意的唯一断言是,这是一个简单的问题:“您至少犯了2个错误。首先:您误以为是一个简单的问题”
是的,这是一个简单的问题,鉴于您提供的详细信息,我已经提供了一个答案,该答案是正确的,并且甚至不能被当前答案无效。
请删除您的答案,因为这是误导和错误的。它当然不应该被接受。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句