等待 form.submit() / POST 完成

2023-12-14

我陷入了一个非常奇怪的境地。解释起来很复杂,但我会尽力。

问题详细解释:

在每次顶部导航单击(绿色甜甜圈/圆圈)或下一步按钮时,我必须提交表单(如果存在且有效)。如果无效,form.valid() 会触发验证错误并返回 false 将停止任何进一步的传播。这个设置运行得非常完美,直到我注意到一种奇怪的行为,这种行为不是很持久。具体来说,我的第三个选项卡上的表单数据量很大。当我点击下一步按钮时,它实际上应该经历相同的过程:检查现有表单(如果有效),然后提交。 Submit 调用 POST 操作方法,当 post 完成时,它会获取下一个选项卡的视图。它的工作方式有 5/10 次,但有时 GET 在 POST 之前执行,这会导致下一页加载不完整的数据。当我设置断点进行调试时,我看到下一个选项卡的 GET 在当前选项卡的 POST 之前执行。

用户界面解释:

我有一个带有 4 个导航的 UI<a>顶部的按钮 - 在中心总是有一个表单 - 在底部我有上一个和下一个按钮。

enter image description here

表单是在 MVC 中使用构建的Ajax.BeginForm

对于每个导航链接<a>元素在顶部,我有一个 JavaScript 函数

var LoadTabs = function (e, arg) {  
    // This is to validate a form if one of the top links is clicked and form has incomplete fields...
    if (arg !== "prev" && arg !== "next") {
        if (!window.ValidateForm(false)) return false;
    }

    var url = $(this).attr('data'); // this contains link to a GET action method
    if (typeof url != "undefined") {
        $.ajax(url, { context: { param: arg } }).done(function (data) {                
            $('#partialViewContainer').html(data);
        });
    }
}

上面的这个函数绑定到页面加载时的每个顶部链接。

$('.navLinks').on('click', LoadTabs);

我的下一个和上一个按钮基本上会触发单击事件,即LoadTabs功能。

$('button').on('click', function () { 
        if (this.id === "btnMoveToNextTab") {
            if (!window.ValidateForm(true)) return false;                

            $.ajax({
                url: url,
                context: { param: 'next' },
                method: "GET",
                data: data,
                success: function(response) {
                    if (typeof response == 'object') {
                        if (response.moveAhead) {
                            MoveNext();
                        }
                    } else {
                        $('#mainView').html(response);
                    }
                    ScrollUp(0);
                }
            });
        } 

        if (this.id === "btnMoveToPreviousTab") {
            MoveBack();
        }
        return false;
    });


MoveNext() Implementation is as below:

function MoveNext() {        
    var listItem = $('#progressbarInd > .active').next('li');        

    listItem.find('.navLink').trigger('click', ['next']);
    ScrollUp(0);
}

问题是,由于某些原因,当导航链接 3 处于活动状态并且我点击“下一步”按钮时 - 不是首先通过 form.submit() 发布表单 - 导航 4 被触发 - 因此导航 4 的 GET 在导航的表单 POST 之前运行3.

我的 ValidateForm 方法基本上只是检查表单是否存在并且有效,然后提交,否则返回 false。其如下:

function ValidateForm(submit) {

    var form = $('form');

    // if form doesn't exist on the page - return true and continue
    if (typeof form[0] === "undefined") return true;

    // now check for any validation errors
    if (submit) {
        if (!$(form).valid()) {                
            return false;
        } else {
            $(form).submit();
        }
    } 
    else {
        return true;
    }

    return true;
}

我的猜测是 form.submit 确实会被触发,但由于提交需要更长的时间才能完成,因此它会继续按钮中的下一个代码块onclick event.

我首先认为这是一个服务器端问题,因为在 POST 中我用几个循环保存了大量数据,并且任何处理繁重的代码块我都有该部分

var saveTask = Task.Factory.StartNew(() => ControllerHelper.SomeMethod(db, model)); Task.WaitAll(saveTask);

WaitAll 将等待并暂停执行,直到 SomeMethod 完成执行。我不确定如何在 JavaScript 中锁定进程并等待它完成执行。因为我想如果我可以以某种方式锁定 ValidateForm 中的 form.submit() 直到其完成处理..也许通过回调方法...

如果有人能引导我走向正确的方向,我将非常感谢您的帮助。如果您需要更多信息,请告诉我,我很乐意提供!


Ajax 是异步的,您的表单提交正在使用Ajax.BeginForm()正在使用ajax。发生的情况是,当您单击“下一步”按钮时,会触发$('button').on('click', function () { code:

  1. 你打电话给ValidateForm()函数(并假设其有效), 你的$(form).submit();代码行开始进行 ajax POST
  2. 代码进入最终阶段return true;行而ajax 呼叫正在执行。
  3. 因为ValidateForm()函数返回true,则$.ajaxGET 调用现在开始,但此时 ajax POST 在ValidateForm()函数可能尚未完成执行导致 您的 GET 方法返回无效数据

您需要更改代码,以便在 POST 方法调用完成后立即进行 GET 调用。自从你使用$.ajax()整个代码中的方法,以及$.ajax()给你更多的灵活性,似乎没有必要使用Ajax.BeginForm()(以及包括的额外开销jquery.unbtrusive-ajax.js脚本)。您还应该处理表格.submit()函数(如果您不希望“下一步”按钮成为表单中的提交按钮,您可以触发.submit()按钮中的事件.click()处理程序)

$(document).on('submit', 'form', function(e) {
    e.preventDefault(); // cancel default submit
    var form = $(this);
    if (!form.valid()) {
        return; // will display the validation errors
    }
    .... // get the relevant urls to the GET and POST methods etc
    $.post(postUrl, form.serialize(), function(data) {
        .... // not clear if your [HttpPost] method returns anything
    }).done(function() {
        $.get(getUrl, someData, function(response) {
            .... // Update the DOM with the next form?
            .... // Re-parse the validator for client side validation
        }
    }).fail(function() {
        .... // code that you might run if the code in the [HttpPost] method fails
    });
});

您还应该考虑返回适当的“下一个”视图[HttpPost]方法,这样您就不需要再次调用服务器来获取它。

也值得一读延迟对象文档以及使用$.when(), $.then() etc.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

等待 form.submit() / POST 完成 的相关文章

  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • C#6 中的长字符串插值行

    我发现 虽然字符串插值在应用于现有代码库的字符串 Format 调用时非常好 但考虑到通常首选的列限制 字符串对于单行来说很快就会变得太长 特别是当被插值的表达式很复杂时 使用格式字符串 您将获得一个可以拆分为多行的变量列表 var str
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • select2 验证 - 选择至少一个值

    我在用select2 http ivaynberg github io select2 and jQuery 验证 http jqueryvalidation org 插件 select2 的 HTML div class form gro
  • 引用/指针失效到底是什么?

    我找不到任何定义指针 引用无效在标准中 我问这个问题是因为我刚刚发现 C 11 禁止字符串的写时复制 COW 据我了解 如果应用了 COW 那么p仍然是一个有效的指针并且r以下命令后的有效参考 std string s abc std st
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 当rest api应用程序服务器(express)和Angulars js应用程序在不同端口上运行时出现Cors问题

    我有用node js编写的rest api应用程序 express在端口3000上运行 而angularjs应用程序在同一服务器上的端口9001上运行 从 angularjs 应用程序调用 rst api 时 出现了 cors 问题 在re
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • chrome 选项卡/窗口中的 window.open 行为

    我有一小段 javascript 旨在打开两个或更多选项卡 这在 FF 和 IE 中工作正常 但 chrome 会在新窗口而不是选项卡中打开第二个窗口 它不依赖于 url 因为我已经尝试过使用两个相同的 url 第一个在选项卡中打开 第二个
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • 选择查询不适用于使用Parameters.AddWithValue 的参数

    C 中的以下查询不起作用 但我看不出问题所在 string Getquery select from user tbl where emp id emp id and birthdate birthdate cmdR Parameters
  • JavaScript setTimeout 和更改系统时间会导致问题

    我注意到如果我设置setTimeout未来1分钟 然后将我的系统时间更改为过去5分钟 setTimeout功能将在 6 分钟后触发 我这样做是因为我想看看夏令时系统时钟更改期间会发生什么 我的 JavaScript 网页使用setTimeo
  • 如何禁用网页中的萤火虫?

    如何使用 Javascript 禁用 firebug 我想这样做是为了向访问者隐藏我的网页的运作方式 有什么选择可以做到这一点吗 你不能 你能做的最好的事情就是混淆你的 JavaScript 实际上刮掉了 您能做的最好的事情就是将所有安全关
  • C++ 中 void(*)() 和 void(&)() 之间的区别[重复]

    这个问题在这里已经有答案了 在此示例代码中 func1是类型void int double and funky是类型void int double include
  • jQuery:向左滑动和向右滑动

    我见过slideUp and slideDown在 jQuery 中 左右滑动的功能 方式怎么样 您可以使用 jQuery UI 中的附加效果来做到这一点 详情请参阅此处 http docs jquery com UI Effects Sl
  • jQuery UI 对话框 - 关闭后无法打开

    我有一个问题jquery ui dialog box https jqueryui com dialog 问题是 当我关闭对话框然后单击触发它的链接时 除非刷新页面 否则它不会再次弹出 如何在不刷新实际页面的情况下回调对话框 下面是我的代码
  • eventSources 到事件 Json,完整日历

    我正在尝试从 eventSources 获取 json 调用到我的事件 我在 eventSources 中返回的 json 是 title Title Test start 1305841052 当我将此字符串传递到事件中时 它会正确显示日
  • 有序 JSON 对象

    我有一个 servlet 它与数据库通信 然后返回有序 按时间排序 对象的列表 在servlet部分 我有 access DB returns a list of User objects ordered ArrayList users M
  • YouTube 点击时禁用 HTML5

    有没有办法让我们通过javascript禁用HTML5视频的 播放 暂停 点击全屏 功能 然后在我们再次需要时将其放回去 我不知道你是否可以禁用它们 但你可以使用 css 删除它们 video webkit media controls f

随机推荐