【问题标题】:Ajax submit makes a full post after first submitAjax submit 在第一次提交后进行完整的发布
【发布时间】:2011-04-09 10:51:14
【问题描述】:

第一次提交按预期工作,但下一次完全回发。我正在使用 jQuery.form 插件,特别是 .ajaxSubmit(options) 调用来提交表单。有几个级别的包装器 div,但我调试了 button.click 绑定,但我无法弄清楚为什么第二次,即使使用相同的变量,它也会完成一个完整的帖子,而我的部分视图返回一个全新的页面。

这里,buttonidscreenid 在两个帖子上都是相同的。我指出这一点是因为它们是按照命名约定计算的,例如 <name>Outer(包装器)、<name>(更新目标)和 <name>Form(要提交的表单)

$('.formButton').click(function () {
    var buttonid = $(this).attr('id');
    var screenid = $('#' + buttonid).closest('div:not(.CSRForm)').attr('id').replace('Outer', '');
    //appends a hidden element so I know which button was pressed when posted
    $('#' + screenid + 'Form').append('<input type="hidden" name="submitButton" value="' + buttonid.replace(screenid, '') + '" />');
    $('#' + screenid + 'Form').submit();
}); 

注意.formButton 元素在表单中不是,这就是为什么我必须这样绑定提交事件。我的部分视图只返回表单而不是按钮(它们是动态的)

这里是 .ajaxSubmit:

$('.CSRForm').submit(function () {
    var needsValidation = "yes";
    if (needsValidation) {
        $(this).ajaxSubmit({
            target: '#AccountSetup',
            replaceTarget: false,
            success: StepCallWithForm //to check whether the response is valid for redirecting
        });
        return false;
    }
}); 

以及我的 MVC 操作(如果相关):

    public ActionResult AccountSetup(AccountSetupViewModel vm, string submitButton)
    {
        if (!ModelState.IsValid)
        {
            return PartialView(vm);
        }
        else
        {
            return Content(submitButton + ",AccountSetup");
        }
    }

编辑: 在我的$(function() { 中立即插入这一行后:

$('#AccountSetup').ajaxForm();

我能够停止完整的回发。在 Firebug 中,现在我看到 ajax 回发到 /CSR/Home/CSR?,这是所有这些东西的开始。这就像表单失去了它的动作属性。我的事件是否以某种方式交火?

【问题讨论】:

    标签: jquery asp.net-mvc ajax jquery-plugins


    【解决方案1】:

    如果您将成功回调中的原始表单替换为部分视图,则可能会发生这种情况。

    因此,当您删除一些 HTML 元素(例如用服务器的部分视图替换现有 HTML)时,它们的所有事件也都消失了。重新添加相同的 HTML(从您的角度来看)只是浏览器的一些新 HTML。它不假设这个新的 HTML 是否与旧代码相关。这就是为什么如果您希望新表单像以前一样工作,您必须重新添加所有功能和事件。

    如果这是您的情况,表单将不再附加submit Ajax 操作,因此第二次它将执行完整的发布。为此,您需要在成功函数中重新附加提交事件:

    $(function() {
        ajaxifyForm();
    });
    
    function ajaxifyForm() {
        $('#AccountSetup').ajaxForm({
            target: '#AccountSetup',
            replaceTarget: false,
            success: stepCallWithForm
        });
    }
    
    function stepCallWithForm(result) {
        // If you replace the #AccountSetup form with the 
        // returned partial result you need to reattach the AJAX submit:
        ajaxifyForm();
    }
    

    【讨论】:

    • 我要添加其他信息:“当您删除现有的 HTML(您的表单)时,它的所有元素及其事件也被删除。所以当重新添加相同的 HTML(可能是基本上任何东西)你也必须重新操作它(附加事件和类似的东西)。”这将更好地解释为什么他必须重新附加事件的情况。
    • @Robert,说得好,请随时编辑我的帖子以包含这些有价值的信息。
    • 我应该指出我在这个页面上有多个表单,类.CSRForm,所以我应该改用Sohnee的解决方案吗? 或者,我可以在.ajaxSubmit 成功回调中使用$form 参数吗?我在最近的一篇文章中提到了这个参数,特别是我不确定它是如何使用的,但也许它是新的形式。 Sohnee 的解决方案听起来更简单——就像我可以绑定一次并忘记它一样。
    • 我尝试了两种方式,.live 绝对是最少的代码量。谢谢!
    【解决方案2】:

    您可以使用 jQuery 的 live() 事件绑定,而不是绑定到 click 事件,它可以在 AJAX 加载后继续存在。您可以通过替换来做到这一点:

    $('.formButton').click(function () {
    

    $('.formButton').live("click", function () {
    

    【讨论】:

    • 我很惊讶我是第一个 +1 的人。 live() 岩石
    【解决方案3】:

    我知道这是一个老问题,但我只是想加我的 2 美分。

    @Sohnee 的回答将起作用:live() 完成了这项工作。但是,它一直是deprecated。应该换成on:

    $("#WrapperDiv").on({
          click:myFunction
       },"#formButton");    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 2015-05-19
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多