【问题标题】:Dynamically created Partial View does not call controller action on submit动态创建的局部视图不会在提交时调用控制器操作
【发布时间】:2016-05-30 15:02:58
【问题描述】:

我正在使用 AJAX 将引导模式内容替换为这样的部分视图:

主视图 HTML

   <div class="container row form-horizontal">
        <div id="myModal" class="modal fade" role="dialog">
            <div class="modal-dialog">
                <!-- Modal content-->
                <div class="modal-content" id="myModalContent">

                </div>
            </div>
        </div>
    </div>

主视图内的 AJAX 脚本

  $(function () {
    $.ajaxSetup({ cache: false });
    $(document).on('click', 'a[data-modal]', function (e) {
        $('#myModalContent').load(this.href, function () {
            $('#myModal').modal({
                keyboard: true
            }, 'show');
            bindForm(this);

            $("form").removeData("validator");
            $("form").removeData("unobtrusiveValidation");
            $.validator.unobtrusive.parse("form");

        });



        return false;
    });
});

function bindForm(dialog) {
    $('form', dialog).submit(function () {
        $('#progress').show();
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                if (result.success) {
                    $('#myModal').modal('hide');
                    $('#progress').hide();
                    alert('reloading');
                    location.reload();
                } else {
                    $('#progress').hide();
                    $('#myModalContent').html(result);
                    bindForm();
                }
            }
        });
        return false;
    });
}

部分视图 HTML

@model MVC_Replica.Models.Location

<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 class="modal-title">Add New Location</h3>
</div>


@using (Html.BeginForm("Create","Locations",FormMethod.Post))
{
@Html.AntiForgeryToken()

<div class="modal-body">

    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.LocationName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LocationName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LocationName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.DateCreated, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.DateCreated, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.DateCreated, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LocationState, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LocationState, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LocationState, "", new { @class = "text-danger" })
            </div>
        </div>


    </div>
</div>
<div class="modal-footer">
    <span id="progress" class="text-center" style="display: none;">
        <img src="~/media/ajax-loading.gif" alt="wiat" />
        Wait..
    </span>

    <input type="submit" class="btn btn-primary pull-left" value="Create" />
    <button class="btn btn-warning" data-dismiss="modal">Close</button>
</div>

}

结果

模式正确打开,客户端验证运行良好。但是,当我submitpartial view 时,永远不会执行以下控制器操作:

        [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Location location)
    {
        if (ModelState.IsValid)
        {
            location.DateCreated = DateTime.Now;
            db.Locations.Add(location);
            db.SaveChanges();
            return Json(new { success = true });
        }

        return PartialView("_CreateLocation", location);
    }

我尝试在ModelState.IsValid 旁边放置一个刹车点,但它永远不会被击中。另外,浏览器控制台也没有显示任何错误

可能是什么问题?

编辑

通过将anchor href 值存储在global variable 中并更改bindForm 函数,我设法让局部视图调用创建操作控制器:

 var actionUrl;
$(function () {

    $('form').submit(function () {

       // alert(this.action);
    });
    $.ajaxSetup({ cache: false });
    $(document).on('click', 'a[data-modal]', function (e) {
        actionUrl = this.href;

        $('#myModalContent').load(this.href, function () {

            $('#myModal').modal({
                keyboard: true
            }, 'show');

            bindForm();

            $("form").removeData("validator");
            $("form").removeData("unobtrusiveValidation");
            $.validator.unobtrusive.parse("form");

        });

        return false;
    });
});
function bindForm() {
    $('form').on('submit',function () {

        $('#progress').show();
        $.ajax({
            url: actionUrl,
            type: 'POST',
            data: $(this).serialize(),
            success: function (result) {
                if (result.success) {
                    $('#myModal').modal('hide');
                    $('#progress').hide();

                    location.reload();
                } else {
                    $('#progress').hide();
                    $('#myModalContent').html(result);
                    bindForm();
                }
            }
        });
        return false;
    });
}

【问题讨论】:

  • 会发生什么?在最坏的情况下,表单应该尝试以传统方式发布,而不使用 AJAX,因此页面应该更改为 something。如果您的 AJAX 工作正常,那么您一定会收到某种响应,即使它只是 404 或 500。在浏览器的开发控制台中查找 AJAX 请求并检查响应。
  • 嗨,克里斯,发生了回发,并调用了我的主视图 HttpGet 操作结果
  • 默认情况下,操作同时接受 GET 和 POST。这意味着您的问题有两个方面:1)错误的 URL 被发布到和 2)表单以传统方式发布,而不是通过 AJAX。首先,您需要检查您的路由并查看上面有什么。其次,您可能需要使用委托,因为 JavaScript 代码在被替换后可能不会应用于新的表单代码。
  • 我注意到 bindForm 函数没有被执行。我尝试使用“on”委托而不是 bindFunction().sumbit,我得到了相同的结果。但是,一旦我删除了 bidnForm 函数中的对话框选择器,它就会正确执行 AJAX 调用,但会调用索引操作结果而不是所需的创建操作。所以我想我有一个额外的线索来解决这个问题。有什么想法吗?
  • 通过委托,我的意思是您需要绑定到永远不会被替换的表单的父元素,并通过选择器将其“委托”到表单。例如,$('#myModalContent').on('submit', 'form', function () { /* do something * }); 之类的东西。换句话说,您将绑定到这个不会更改的 div,并让它将任何提交事件委托给它在事件发生时找到的任何表单元素。

标签: jquery ajax asp.net-mvc twitter-bootstrap partial-views


【解决方案1】:

所以create controller action 从未被调用的原因是因为bindForm 函数的submit 事件从未被执行。正如我所发现的,bindForm 函数中的dialog selector 阻止了事件被触发。我已对解释可能解决方案的问题进行了编辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-07
    • 2012-02-19
    • 2013-12-15
    • 1970-01-01
    • 2010-11-25
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多