3

I am using MVC4. Unobtrusive JavaScript is enabled and referenced in my project. The Ajax scripts are loading in my shared master page. FireBug reports no errors or 404's.

I have added a Text box to my page, which updates the contents of a Hidden field inside of my Ajax form. When a user presses a key, and the KeyUp event fires, I force my Ajax form to submit by calling:

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

Where ajaxForm is the name of the Ajax form. This works fine. The form is submitted, behind the scenes, and my controller event fires. The Model is updated with the new data, based on the input from the user.

However, where it gets strange, is when the result returns to my form. The entire contents of my form div tag is replaced by the result -- which is the entire page.

<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>
  • Notice how basic-modal-content now contains itself, another basic-modal-content. The result div should only contain the updates results, not the entire view -- obviously.

My code is as follows:

View (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>

Controller (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);
}

I'm not sure where I'm going wrong on this. I've spent hours trying to figure this out. Any solutions?

4

3 回答 3

11

第一个问题是您使用了错误的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
)

现在真正的问题是您需要将#resultsdiv放在局部视图之外和主视图内:

<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
)
于 2012-05-25T12:34:44.337 回答
0

前几天我有类似的事情。

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

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

对不起,它有点含糊,但希望它会对你有所帮助。

于 2012-05-25T12:10:43.927 回答
0

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

于 2012-05-25T12:15:36.370 回答