MVC Ajax 表单返回 View 的全部内容

Posted

技术标签:

【中文标题】MVC Ajax 表单返回 View 的全部内容【英文标题】:MVC Ajax Form returning entire contents of View 【发布时间】:2012-06-01 00:18:25 【问题描述】:

我正在使用 MVC4。在我的项目中启用并引用了不显眼的 javascript。 Ajax 脚本正在我的共享母版页中加载。 FireBug 没有报告任何错误或 404。

我在我的页面中添加了一个Text 框,它更新了我的Ajax 表单内的Hidden 字段的内容。当用户按下一个键并触发 KeyUp 事件时,我通过调用强制我的 Ajax 表单提交:

$("form#ajaxForm").trigger("submit");

其中 ajaxForm 是 Ajax 表单的名称。这工作正常。表单在幕后提交,我的控制器事件触发。模型会根据用户的输入使用新数据进行更新。

然而,奇怪的是当结果返回到我的表单时。我的表单div 标记的全部内容被替换为结果——即整个页面。

<div id="basic-modal-content"">
   <input id="breed" type="text"/>
<div>
<form id="ajaxForm" method="post" data-ajax-update="#results" data-ajax-mode="replace" data-ajax="true" action="/Poultry/ListBreeds?Length=7">
   <div id="results">
    ->THIS AREA IS GETTING REPLACED WITH THE ENTIRE FORM <-
      <div id="basic-modal-content">
      </div>
   </div>
</form>
注意 basic-modal-content 现在如何包含自己,另一个 basic-modal-content。结果 div 应该只包含更新结果,而不是整个视图——显然。

我的代码如下:

查看 (BreedSelectorPartial.cshtml)

@model IQueryable<Inert.BreedViewModel>

<script type="text/javascript">
    $(document).ready(function () 
        $("#breed").keyup(function (e) 
            $("input[name=breedSearch]").val($("#breed").val());
            $("form#ajaxForm").trigger("submit");
        );
    );
</script>

<div id="basic-modal-content">
<input id="breed" type="text" style="width:100%; height:22px;" />
    <div>
        <div style="margin-top: 4px;">
            <label for="breed">Begin by typing a breed, e.g. <span style="font-style: italic">Wyandotte</span></label>
        </div>
    </div>
    @using (Ajax.BeginForm("ListBreeds", "Poultry", new AjaxOptions UpdateTargetId = "results" , new  id = "ajaxForm" ))
    
        <input id="breedSearch" name="breedSearch" type="hidden" />
    
    <div id="results" style="height: 320px; color: black; margin-top: 12px; font-size: 18px;">
        @
            var grid = new WebGrid(Model, ajaxUpdateContainerId: "results");
            int c = Model.Count();
         
        @grid.GetHtml(tableStyle: "webgrid",
            alternatingRowStyle: "webgrid-alternating-row",
            rowStyle: "webgrid-row-style",
            displayHeader: true)
    </div>
</div>
<script type="text/javascript" src="/scripts/jquery.simplemodal.js"></script>
<script type="text/javascript" src="/scripts/basic.js"></script>

控制器 (PoultryController.cs)

[HttpPost]
public ActionResult ListBreeds(string breedSearch)

    InertDatabaseEntitiesConnection db = new InertDatabaseEntitiesConnection();
    var breeds = db.Breeds.Where(q => q.Name.Contains(breedSearch));
    var names = breeds.Select(q => new BreedViewModel  Name = q.Name );
    return PartialView("BreedSelectorPartial", names);

我不确定我在哪里出错了。我花了几个小时试图弄清楚这一点。有什么解决办法吗?

【问题讨论】:

它是因为您的视图模型显示模板...您返回的对象与您的主视图模型匹配 @model IQueryable...所以它直接调用该视图 你能显示你BreedSelectorPartial.cshtml部分的内容吗? @DarinDimitrov 上面的标记代码是BreedSelectorPartial.cshtml 视图。我正在尝试做的是让视图调用自己以获取更新的模型——但只用更改替换 results div 中的区域。 好的,我以为这是你的主要观点。没有仔细阅读你的问题。现在一切都清楚了。看我的回答。 #results div 必须在主视图中的部分之外。 【参考方案1】:

第一个问题是您使用了错误的 Ajax.BeginForm 帮助程序重载(但这不会导致不良行为,它只是一个旁注):

@using (Ajax.BeginForm(
    "ListBreeds",                                      // actionName
    "Poultry",                                         // routeValues
    new AjaxOptions  UpdateTargetId = "results" ,    // ajaxOptions
    new  id = "ajaxForm" )                           // htmlAttributes
)

而你需要:

@using (Ajax.BeginForm(
    "ListBreeds",                                      // actionName
    "Poultry",                                         // controllerName
    null,                                              // routeValues
    new AjaxOptions  UpdateTargetId = "results" ,    // ajaxOptions
    new  id = "ajaxForm" )                           // htmlAttributes
)

现在真正的问题是您需要将#results div 放在主视图的部分和内部:

<div id="results" style="height: 320px; color: black; margin-top: 12px; font-size: 18px;">
    @Html.Partial("BreedSelectorPartial")
</div>

当然,如果您只需要更新 WebGrid 部分,那么只将网格保留在部分内部并将表单移到主视图之外会更有意义。

所以你的主视图现在变成了:

@model IQueryable<BreedViewModel>
<script type="text/javascript">
    $(document).ready(function () 
        $("#breed").keyup(function (e) 
            $("input[name=breedSearch]").val($("#breed").val());
            $("form#ajaxForm").trigger("submit");
        );
    );
</script>

<div id="basic-modal-content">
    <input id="breed" type="text" style="width:100%; height:22px;" />
    <div>
        <div style="margin-top: 4px;">
            <label for="breed">Begin by typing a breed, e.g. <span style="font-style: italic">Wyandotte</span></label>
        </div>
    </div>
    @using (Ajax.BeginForm("ListBreeds", "Poultry", null, new AjaxOptions  UpdateTargetId = "results" , new  id = "ajaxForm" ))
    
        <input id="breedSearch" name="breedSearch" type="hidden" />
    
    <div id="results" style="height: 320px; color: black; margin-top: 12px; font-size: 18px;">
        @Html.Partial("BreedSelectorPartial")
    </div>
</div>

唯一需要更新的部分是包含网格的BreedSelectorPartial.cshtml 部分:

@model IQueryable<BreedViewModel>
@
    var grid = new WebGrid(Model, ajaxUpdateContainerId: "results");

@grid.GetHtml(
    tableStyle: "webgrid",
    alternatingRowStyle: "webgrid-alternating-row",
    rowStyle: "webgrid-row-style",
    displayHeader: true
)

【讨论】:

【参考方案2】:

前几天我也遇到过类似情况。

我不记得确切的问题是什么,但它与返回整个对象有关,而不仅仅是对象的 HTML 元素。

目前我找不到代码,但是如果您使用的是 Firebug 或类似的东西,请查看您是否可以监视返回的数据,如果我没记错,我需要做的就是将 .html 添加到行尾。

抱歉有点含糊,但希望对您有所帮助。

【讨论】:

我正在这样做——它用表单替换了 results div 的全部内容。这就是问题所在。【参考方案3】:

您确定您没有进行常规表单提交吗?我认为这条线$("form#ajaxForm").trigger("submit"); 正在做常规表单提交。您可能应该在此处发布 ajax 表单,而不是调用正常的表单提交。因此,您会看到整个页面重新加载。

【讨论】:

整个页面没有重新加载。结果 div 的内容正在重新加载部分视图的全部内容。

以上是关于MVC Ajax 表单返回 View 的全部内容的主要内容,如果未能解决你的问题,请参考以下文章

MVC之Ajax异步操作

ASP.NET MVC 在 Ajax 调用控制器后显示视图

MVC 控制器返回内容与返回 Json Ajax

如何在 ASP.NET MVC 中通过 Ajax 提交表单?

在 MVC 中返回文件或 ajax 警报

处理 Thymeleaf Spring MVC AJAX 表单及其错误消息的推荐方法