MVC 2.0 Ajax:下拉列表上的自动提交导致正常回发

发布于 2024-10-14 06:55:20 字数 2660 浏览 6 评论 0原文

我正在尝试将 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”参数,但它不存在,所以“模式”默认为“电话”,这让整个苹果车感到不安。

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

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

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

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

I am trying to add Ajax functionality to my MVC application. I want a form to post back asynchronously. Here's the form code:

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

and I want it to automatically post back when a dropdown list selected value changes:

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

However, when I try this out, the program posts back normally, not a partial postback as I was expecting. Here's what I think the problem is: onchange = "this.form.submit();" in the dropdown list.

I think that this somehow causes a normal postback instead of the asynchronous postback.

Here's what MVC generates for HTML for the form tag:

<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: 'divInterviewee' });">

I think that with "this.form.submit()" the "onsubmit" event handler is not being called. The thing is, I don't understand why. Wouldn't "onsubmit" catch any event that submits the form?

UPDATE: I went to jquery, thusly:

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

This is causing many problems, among them:

-- It still does not seem to do an asyncrhonous postback. In my controller action method, I have the following code: "if (Request.IsAjaxRequest())" which returns false.

-- I can't seem to do model binding any more. My route looks like :

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

but the route that apparently ends up being sent is

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]

causing the model binding not to work -- "visit" is supposed to be a "mode" parameter, but it's not there so "mode" defaults to "phone", which upsets the whole applecart.

It is the serialize command that is causing this? I don't understand why it would append it to the querystring when the method is POST.

There are other things -- among them, the fact that my action must return a ViewResult, so how can I possibly just return a string, which is all I need using ajax ... but I will defer that concern until I get the routing/binding thing straightened out!

UPDATE: "SetInterviewee" is indeed the correct route to post to, but the routeValues parameter should copy the route values from the current view -- I would think. Here's the code for the form:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后知后觉 2024-10-21 06:55:20

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

在表单中添加一个提交按钮。类似于:

<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 代码似乎工作得很好。试一试吧!

So I know this is quite an old question, but I've been messing around with a similar issue and seem to come to a workaround that might prove useful in the future.

Inside your form, add a submit button. Something like:

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

Make sure that you have specified the name attribute as it seems to matter in this case. Here is the code I have an it is currently working with full model binding:

<% 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>
<% } %>

Granted this is my code and not tied to your example, but you can get the idea from what is going on. Originally I had the dropdownlist just doing a submit and when it fired I was getting all sorts of quirky responses - including a full synchronous postback. When I added the submit button, the MS ajax code seems to work beautifully. Give it a shot!

浮光之海 2024-10-21 06:55:20

我建议您使用 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。

I would recommend you to use jquery and get rid of all Ajax.* helpers and MSAjax scripts.

So:

<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" }
)%>

and then in a separate javascript file:

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

Now we have successfully separated HTML markup from javascript. It is unobtrusive javascript.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文