防止服务器端 Blazor 在 EditForm 中触发 onsubmit

Prevent Server Side Blazor from firing onsubmit in an EditForm

当我在输入字段中按 Enter 时,我想阻止服务器端 Blazor 触发 EditForm 的 OnSubmit 事件处理程序(由于某些其他原因我无法摆脱)。这似乎是一件容易的事,我就是解决不了。 我编了一个我能想到的最小的例子:

_Index.razor:

@page "/"
@inject IJSRuntime JSRuntime;


<EditForm Model="Model" OnSubmit="HandleOnSubmit">
    <input id="testInput"/>
    <button type="submit" value="unneeded submit button"></button>
</EditForm>

@code
{
    private CModel Model { get; set; } = new CModel() { ID = "ID", Name = "Name" };

    private async Task HandleOnSubmit()
    {
        await JSRuntime.InvokeAsync<object>("alert", new object[] { "This alert shouldn't be shown!!" });
    }
}

CModel class(虽然与问题无关):

public class CModel
{
    public string ID { get; set; }
    public string Name { get; set; }
}

和 _Host.cshtml:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PreventSubmitOnForm</title>
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
</head>
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss"></a>
    </div>

    <script src="_framework/blazor.server.js"></script>
    <script>
        document.getElementById("testInput").addEventListener('keypress', function (event) {
            if (event.which === 13) {
                event.preventDefault();
                alert('Form submit prevented');
            }
        });
    </script>
</body>
</html>

在 _Host.cshtml 中,我注册了一个新的 keypress 事件处理程序,并且在我调试时,在创建页面时它会被真正注册。但它永远不会在按键输入时触发。 我已经尝试用 @onkeypress:preventDefault@onkeypress:stopPropagation 来欺骗这种情况,但是当我只想阻止默认行为时,它们似乎没有帮助(正如史蒂夫桑德森宣称的 in his issue comment)我的输入字段和仅用于事件的特定字段:按下 Enter。

在正常的 HTML + JS 案例中,它就像一个魅力:https://jsfiddle.net/wmk608gh/1/

所以我最终采用了 JS Interop 解决方案并添加了脚本

<script>
    document.getElementById("testInput").addEventListener('keypress', function (event) {
        if (event.which === 13) {
            event.preventDefault();
            alert('Form submit prevented');
        }
    });
</script>

到_Host.cshtml。 但它似乎并没有奏效。我想我应该将我的脚本注册到另一个事件(而不是 keypress),或者可能已经有我可以在这里遵循的最佳实践。

感谢任何帮助。

问题是您尝试在 <input /> 元素尚未呈现的时候添加 EventListener。

要完成这项工作,您可以在 blazor 呈现您的页面后调用您的 JS 函数:

在您的 _Index.razor @code 块中添加:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await JSRuntime.InvokeVoidAsync("PreventDefault");
    }
}

在 _Host.cshtml 中用函数包装您的 addEventListener:

<script>
    function PreventDefault() {
        document.getElementById("testInput").addEventListener('keypress', function (event) {
            if (event.which === 13) {
                event.preventDefault();
                alert('Form submit prevented');
            }
        });
    }
</script>