等待 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 完成 的相关文章

  • 在 Three.js 中绕点旋转对象的正确方法是什么?

    关于 Three js 的大多数教程 问题都建议使用 Three js 绕点旋转对象的方法是在要旋转的位置创建父对象 附加对象 然后移动子对象 然后 当父级旋转时 子级围绕该点旋转 例如 Make a pivot var pivot new
  • 可能未处理的承诺拒绝(id 0)类型错误 GET 或 HEAD 请求不允许主体

    import React from react import FlatList ActivityIndicator Text View from react native export default class FetchExample
  • 如何在C中实现带连分数的自然对数?

    这里我有一个小问题 根据这个公式创建一些东西 这就是我所拥有的 但它不起作用 弗兰基 我真的不明白它应该如何工作 我尝试用一 些错误的指令对其进行编码 N 是迭代次数和分数部分 我认为它会以某种方式导致递归 但不知道如何 谢谢你的帮助 do
  • MSBuild 与编译器

    从命令提示符使用 MSBuild 和 C 编译器有什么区别 我想在不使用 Visual Studio 的情况下手动构建我的解决方案 项目 并且我想学习如何使用命令行工具 C 编译器你的意思是csc exe 如果这就是你的意思 那么csc a
  • gcc 没有小字符串优化吗?

    Most std string实现 包括 GCC 使用小字符串优化 例如 有一个answer https stackoverflow com a 21710033 2640636讨论这个 今天 我决定检查我编译的代码中的字符串在什么时候被移
  • 无效 * 算术

    include
  • 如何在使用连接池时强制 SqlConnection 物理关闭?

    我明白 如果我实例化一个 SqlConnection 对象 我实际上是从连接池中获取一个连接 当我调用 Open 时 它将打开连接 如果我对该 SqlConnection 对象调用 Close 或 Dispose 方法 它将返回到连接池 但
  • 从 std::function 调用签名推导模板参数

    考虑这个模板函数 template
  • 如何使用Boost.Asio C++? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我会尝试使用该库在多个平台上使用套接字 Boost Asio c 我在这里下载了最新版本 http sourceforge net p
  • JavaScript 添加布尔值

    console log true true 2 console log typeof true true number console log isNaN true true false 为什么两个布尔类型相加会产生一个数字 我有点理解 如
  • 如何在非托管 ATL GUI 中嵌入 Windows 窗体?

    我有一个使 COM 可见的 Windows 窗体用户控件 现在我想将该控件嵌入到 ATL 对话框 GUI 中 ATL项目 非托管C 只应获取winform的progID并在运行时动态创建和嵌入它 这可能吗 如果可以 我该怎么做 我不确定 A
  • 浏览器视口大小(以设备像素为单位)

    Goal 我希望 Flash 能够获得有关浏览器视口宽度和高度 以设备像素为单位 的准确信息初始化 调整大小或浏览器缩放事件时 规格 我需要将 flash 嵌入到在 chrome safari firefox 等中运行的 html 页面中
  • 根据自定义属性 UWP 禁用某些 ListViewItem

    我有一个ListView其中包含多种类型的自定义UserControls 项目要求其中一些必须是不可点击的 所以我想禁用它们 但是只有他们 这些项目将根据自定义属性的值启用 禁用 我尝试过设置ListViewItem IsEnabled财产
  • 在 C++ 中为哈希映射提供复合键

    我有一个数据结构
  • 如何从 Web API 应用程序返回 PDF

    我有一个在服务器上运行的 Web API 项目 它应该从两种不同类型的源返回 PDF 实际的可移植文档文件 PDF 和存储在数据库中的 base64 字符串 我遇到的问题是将文档发送回客户端 MVC 应用程序 剩下的部分是关于所发生的一切以
  • 为什么 Bind 和 OneWayBind 不总是使用主 UI 线程?

    In my ViewModel我经常会得到如下代码 public bool IsDownloading get return isDownloading Value private ObservableAsPropertyHelper
  • jQuery .push 到 .get 调用中的数组给出空结果

    谁能告诉我为什么下面给我一个空字符串 当我console log contentArray in the get 回调函数它显示数据 但是当我尝试在下面的代码中执行它时 结果为空 sectionArray contentArray func
  • Akka.net 和单元测试

    我想使用 Akka net TestKit 编写单元测试 但我有一个问题 我有一个 SubscriptionService 类 它负责将消息传输给选定的参与者 public class SubscriptionService Receive
  • 使用 Node.js 构建网站的最佳实践

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我想知道如何使用 Node js 从头开始 开发一个网站 我明白我怎么能possibly
  • 如何成功使用 VIM 作为 Code::Blocks 的外部编辑器?

    我真的很喜欢 Code Blocks 的构建系统和单步调试能力 也就是说 我真的很喜欢使用 gcc gdb 的包装器 而不是从 Makefile 或命令行使用它们 问题是 多年来使用 VIM 使我的大脑受到了严重损伤 或者有些人可能会说被宠

随机推荐