防止服务器端 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>
当我在输入字段中按 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>