Blazor EditForm提交处理程序在表单位于Bootstrap模态框中且提交按钮是模态框关闭命令时未被调用。

4

让我们考虑客户端Blazor应用程序中的以下页面:

@page "/test"

<div id="modalDialog" class="modal" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-body">
                <EditForm Model="@model" OnSubmit="@SubmitHandler">
                    <div class="form-group d-flex justify-content-between">
                        <label class="col-form-label col-3" for="editDT">Time</label>
                        <InputText bind-Value="@model" id="editDT" Class="form-control" />
                    </div>
                    <button type="submit" class="btn btn-primary" @*data-dismiss="modal"*@>Submit</button>
                </EditForm>
            </div>
        </div>
    </div>
</div>
<button data-toggle="modal" data-target="#modalDialog" class="btn btn-primary">Open</button>

@functions {
    private string model { get; set; } = "Model";
    private void SubmitHandler()
    {
        Console.WriteLine("Submit");
    }
}

当我点击打开按钮时,模态框出现了,符合预期。然后在模态框中点击提交按钮,“Submit”被打印在浏览器控制台中,也符合预期。
但是,我需要在点击提交时关闭模态框,所以我将data-dismiss属性的注释去掉。现在,模态框如预期关闭,但是“Submit”处理程序不再被调用(浏览器控制台保持为空)。
1)这是预期的行为吗?
2)如果是,则是否有一种方法可以在没有JavaScript互操作的情况下在提交处理程序中关闭模态框?
3)如果不是,是否有另一种方法可以同时关闭模态框并在单击提交按钮时调用“Submit”处理程序,同样不需要使用js互操作?

1
你是想直接使用 BS 模态框,还是已经将其转换为 Blazor? - Chris Sainty
1
我正在使用它,就是原样的。 - Franco Tiveron
4个回答

6
你最大的问题是直接使用Bootstrap。Bootstrap使用自己的JS来操作DOM,而这与Blazor不兼容,因为Blazor需要控制DOM。同样的情况也适用于Angular、React或Vue。如果其他东西修改了DOM,那么奇怪的事情就会发生,就像你现在遇到的一样。
我建议你换用其中一个Blazor化的Bootstrap库,比如BlazorStrap。或者,如果你只是需要一个模态框,我写了一个叫做Blazored.Modal的库。

4
为了在Bootstrap模态框中提交表单,请按照以下步骤进行操作:
1. 给你的表单添加一个id属性 <EditForm id="my-form-ref"> 2. 然后在提交按钮上添加form属性,并将其值设置为表单的id <button type="submit" class="btn btn-danger" form="my-form-ref">提交表单</button>

1
我猜dismiss="modal"只有在使用<button type="button"></button>时才可行,但这不会启用“提交表单”。要真正解决这个问题,我建议您使用<form>标签和<button type="button">标签。
但更好的解决方案是遵循Chris Sainty在他的答案中提出的建议。
我还可以补充说,在Blazor中嵌入Bootstrap对话框似乎不是一个好的实践,因为这样的对象可以很容易地在Blazor中实现...
因此,我建议您自己创建一个对话框组件,一个模板化的组件,也许基于Bootstrap对话框...毕竟,我猜想像我们所有人一样,您正在学习Blazor。所以这可能是一个很好的练习。
希望这可以帮助您...

1

所有的建议都很好。但是,为了完整起见,我找到了一种实现我想要的方式,即使它不是非常优雅的解决方法:

@page "/test"
@using System.ComponentModel.DataAnnotations;

<div id="modalDialog" class="modal" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-body">
                <EditForm EditContext="@EC">
                    <DataAnnotationsValidator />
                    <ValidationSummary />

                    <div class="form-group d-flex justify-content-between">
                        <label class="col-form-label col-3" for="editDT">Time</label>
                        <InputText bind-Value="@model.Name" id="editDT" Class="form-control" />
                    </div>
                    @if (EC.Validate())
                    {
                        <button type="button" onclick="@SubmitHandler" class="btn btn-primary" data-dismiss="modal">Submit</button>
                    }
                    else
                    {
                        <button type="button" onclick="@SubmitHandler" class="btn btn-primary">Submit</button>
                    }
                </EditForm>
            </div>
        </div>
    </div>
</div>
<button data-toggle="modal" data-target="#modalDialog" class="btn btn-primary">Open</button>

@functions {
    public class ModelClass
    {
        [Required]
        public string Name { get; set; }
    }
    private ModelClass model { get; set; } = new ModelClass { Name = "My Name" };
    private EditContext EC { get; set; }
    private void SubmitHandler()
    {
        Console.WriteLine("Submit");
    }
    protected override void OnInit()
    {
        EC = new EditContext(model);
        base.OnInit();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接