为什么Unobtrusive Ajax需要布局页面(返回部分视图不起作用)?

时间:2014-06-18 14:10:50

标签: ajax razor partial-views unobtrusive-ajax

在创建自定义插件时,Ajax化任何尚未被不显眼的Ajax 进行Ajax化的form ,我注意到我的部分/布局代码无法在回发后显示一个正常的不引人注目的Ajax表单:

对于我的其他部分更新插件,我有条件地将页面呈现为部分(对于ajax请求)或完整的布局(对于正常请求),如下所示:

    public ActionResult AjaxForm()
    {
        if (!Request.IsAjaxRequest())
        {
            ViewBag.Layout = "_Layout.cshtml";
        }
        return PartialView();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AjaxForm(AjaxFormModel model)
    {
        if (!Request.IsAjaxRequest())
        {
            ViewBag.Layout = "_Layout.cshtml";
        }

        if (ModelState.IsValid)
        {
            return PartialView("Success", model);
        }

        return PartialView(model);
    }

在测试一个普通的不引人注目的Ajax表单时,我使用了这个测试视图,它只更新了自己的元素UpdateTargetId="FormPanel"

@using (Ajax.BeginForm("AjaxForm", null, new AjaxOptions() { UpdateTargetId = "FormPanel" }, new { id = "FormPanel" }))
{
    @Html.AntiForgeryToken()

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

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

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

如果我删除了测试if (!Request.IsAjaxRequest()),并返回包含母版页/布局的整页,则会在表单所在的位置呈现结果。

Fiddler显示在任何一种情况下都会返回“成功”视图,但如果没有布局,它就不会执行任何操作。

问。什么是主页/布局中不显眼的Ajax需要提取内容并替换指定的元素

更新

更糟糕的是它第一次实际上正常工作,但是如果我再次加载相同的表单则不行。

1 个答案:

答案 0 :(得分:0)

答:表格必须有唯一的ID!

在SO上有很多关于唯一ID的问题,浏览器通常会处理这些问题,但是你不能破坏的问题是有两个表单加载了相同的id。 JavaScript / jQuery只能看到一个!

我的问题是由重复的表单ID引起的。 您不应将结果页面重新插入表单本身(保持表单元素不变)。

当我在幻灯片式控件中动态重新加载原始表单时,我结束了重复的表单ID。

这意味着Unobtrusive Ajax只能看到DOM中的第一个表单!

解决方案(不要设置Ajax表单自行更新):

如果您动态加载面板,请将UpdateTargetId设置为表单上方的元素,而不是表单本身。

修复我的示例视图(带目标面板的环绕声表单):

<div id="FormPanel">
    @using (Ajax.BeginForm("AjaxForm", new AjaxOptions() { UpdateTargetId = "FormPanel" }))