【问题标题】:Why does Unobtrusive Ajax require a layout page (returning a partial view doesn't work)?为什么 Unobtrusive Ajax 需要布局页面(返回局部视图不起作用)?
【发布时间】:2014-06-18 22:37:12
【问题描述】:

在创建自定义插件时,该插件会 Ajaxify 任何 forms 尚未被不显眼的 Ajax 进行 Ajaxified,我注意到我的部分/布局代码无法在回发时正常显示不显眼的 Ajax 形式:

对于我的其他 partial-update 插件,我有条件地将页面呈现为部分(对于 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 在母版页/布局中需要什么

更新:

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

【问题讨论】:

  • 通常布局页面会有脚本标签来加载相关库,而部分页面没有这些,因此不会加载 JavaScript。
  • @Nigel Ellis:是的,但这是一个 Ajax 更新并且脚本已经加载。目前正在寻找更多线索。
  • 我认为还没有足够的信息;我们需要看看您的脚本如何改变表单的行为以使其更具决定性。
  • @Brad Christie:当场.. 刚刚找到原因,而且它 晦涩难懂(答案即将出现)。
  • 问题不是我想的那样,但答案(下)非常有用,值得了解。感谢所有建议:)

标签: ajax razor partial-views unobtrusive-ajax


【解决方案1】:

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

关于 SO 上的唯一 ID 存在大量问题,浏览器通常会处理这些问题,但您永远无法破解的问题是加载了两个具有相同 ID 的表单。 JavaScript/jQuery 只有一个可见!

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

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

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

解决办法(不要设置Ajax表单自己更新):

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2014-12-13
    相关资源
    最近更新 更多