2

我正在尝试将 Ajax 功能添加到我的 MVC 应用程序中。我想要一个异步回发的表单。这是表单代码:

using (Ajax.BeginForm("SetInterviewee", "Date", routeValues, new AjaxOptions { UpdateTargetId = "divInterviewee" }))

我希望它在下拉列表中选择的值发生变化时自动回发:

<%= Html.DropDownList("interviewees", Model.interviewees.intervieweeLists.intervieweesList, "-- select employee --", new { @class = "ddltext", style = "width: 200px", onchange = "this.form.submit();" })%>

但是,当我尝试这个时,程序正常回发,而不是我期望的部分回发。这就是我认为的问题所在: onchange = "this.form.submit();" 在下拉列表中。

我认为这会以某种方式导致正常的回发而不是异步回发。

下面是 MVC 为表单标签生成的 HTML:

<form action="/SetInterviewee/2011-1-26/2011-1/visit" method="post" onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));" onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: &#39;divInterviewee&#39; });">

我认为使用“this.form.submit()”不会调用“onsubmit”事件处理程序。问题是,我不明白为什么。“onsubmit”不会捕获任何提交表单的事件吗?

更新:我去了jquery,因此:

        $(function () {
        $('#interviewees').change(function () {
            var form = $('#intervieweeForm');
            $.ajax({
                url: form.attr('action'),
                type: form.attr('method'),
                data: form.serialize(),
                success: function (result) {
                    $('#selectedInterviewee').val(result);
                }
            });
        });
    });

这导致了许多问题,其中包括:

- 它似乎仍然没有进行异步回发。在我的控制器操作方法中,我有以下代码:“if (Request.IsAjaxRequest())”,它返回 false。

-- 我似乎不能再做模型绑定了。我的路线看起来像:

http://localhost:1986/Interviews/2011-2-25/2011-2/visit

但显然最终被发送的路线是

http://localhost:1986/SetInterviewee/2011-2-25/2011-2?
Count=5&Keys=System.Collections.Generic.Dictionary`2+KeyCollection
[System.String,System.Object]
&Values=System.Collections.Generic.Dictionary`2+ValueCollection
[System.String,System.Object]

导致模型绑定不起作用——“visit”应该是一个“mode”参数,但它不存在,所以“mode”默认为“phone”,这会扰乱整个 Applecart。

是导致这种情况的序列化命令吗?我不明白为什么当方法是 POST 时它会将其附加到查询字符串中。

还有其他一些事情——其中,我的操作必须返回一个 ViewResult,所以我怎么可能只返回一个字符串,这就是我使用 ajax 所需要的......但我会推迟这个问题,直到我得到路由/绑定的东西理顺了!

更新:“SetInterviewee”确实是发布到的正确路线,但 routeValues 参数应该从当前视图复制路线值——我想。这是表单的代码:

RouteValueDictionary routeValues = ViewContext.RouteData.Values;
using (Html.BeginForm("SetInterviewee", "Date", routeValues, FormMethod.Post, new { id = "intervieweeForm" }))
4

2 回答 2

1

所以我知道这是一个相当古老的问题,但我一直在处理类似的问题,并且似乎找到了一种可能在未来证明有用的解决方法。

在您的表单中,添加一个提交按钮。就像是:

<input type="submit" name="submit" value="save" style="display: none;" />

确保您已指定 name 属性,因为它在这种情况下似乎很重要。这是我目前正在使用完整模型绑定的代码:

<% using (Ajax.BeginForm("SaveStatus", "Finding", new { FindingId = Model.FindingId },
       new AjaxOptions {
           HttpMethod = "Post",
           InsertionMode = InsertionMode.Replace,
           UpdateTargetId = "StatusWindow",
           OnBegin = "function(){ jQuery('#SaveStatusForm').block({ Message: 'Saving' }); }",
           OnComplete = "function(){ jQuery('#SaveStatusForm').unblock(); }",
           OnFailure = "HandleMSAjaxFail",
       }, new { id = "SaveStatusForm" })) { %>
<div>
    <%: Html.DropDownListFor(Status => Status.SelectedTagId, Model.AvailableStatuses, null, new Dictionary<string, object> { { "onchange", "jQuery('#SaveStatusForm').submit();" } })%>
    <input type="submit" name="submit" value="save" style="display: none;" />
</div>
<% } %>

当然,这是我的代码,与您的示例无关,但您可以从正在发生的事情中得到这个想法。最初我的下拉列表只是进行提交,当它被触发时,我得到了各种古怪的响应——包括一个完整的同步回发。当我添加提交按钮时,MS ajax 代码似乎运行良好。试一试!

于 2011-11-30T05:30:22.757 回答
0

我建议您使用 jquery 并摆脱所有Ajax.*帮助程序和MSAjax脚本。

所以:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

<% using (Html.BeginForm("SetInterviewee", "Date", routeValues, FormMethod.Post, new { id = "myform" })) { %>
    ...
<% } %>

<%= Html.DropDownList(
    "interviewees", 
    Model.interviewees.intervieweeLists.intervieweesList, 
    "-- select employee --", 
    new { id = "interviewees", @class = "ddltext", style = "width: 200px" }
)%>

然后在一个单独的 javascript 文件中:

$(function() {
    $('#interviewees').change(function() {
        var form = $('#myform');
        $.ajax({
            url: form.attr('action'),
            type: form.attr('method'),
            data: form.serialize(),
            success: function(result) {
                 $('#divInterviewee').html(result);
            }
        });
    });
});

现在我们已经成功地将 HTML 标记与 javascript 分开了。它是不显眼的 javascript。

于 2011-01-26T08:28:40.100 回答