【问题标题】:Stop event from continuing on deferred.reject停止事件在 deferred.reject 上继续
【发布时间】:2017-08-17 22:33:11
【问题描述】:

希望你们中的一些人可以帮助我解决这个问题。

我的应用程序顶部有一些导航链接,它们具有活动和非活动状态。理论上,我想从一个跳转到另一个,如果存在不完整/有效的表单,我会触发验证错误并留在同一页面上。在我的情况下发生的情况是表单验证工作正常,但顶部的导航链接将状态从非活动更改为活动,以点击者为准。

我有一个 ValidateForm 函数,它验证并提交表单是否有效,否则返回 deferred.reject();

function ValidateForm(submitAnyway) {
    var deferred = $.Deferred();
    var form = $('form');

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


    // now check for any validation errors
    if (submitAnyway) {
        if (!$(form).valid()) {                
            deferred.reject();
        } else {
            $(form).submit();
            deferred.resolve();
        }
    } else {
        deferred.resolve();
    }

    return deferred.promise();
}

我对这些顶部导航链接有一个点击事件,如下所示:

var DonutsClickEvent = function (e, arg) {
    var url = $(this).attr('data');
    var data = { param: arg };

    if (typeof url === "undefined") return false;

    $.when(window.ValidateForm(false)).then(
        function () {
            LoadPartialView_Main(url, data);                
        },
        function(){
            return false; // I'm trying to return false here to stop event from continuing 
        }
    );  
    Console.log("This statement runs before $.when completes");
    // and event continues and the clicked nav button changes 
    // its state from non-active to active, even though form doesn't validate
}

我最近在我的代码中添加了 $.Deferred 功能,因为某些事件以混乱的顺序触发...在我的 validateForm 方法返回 true 或 false 之前,如果为 true,我将继续执行事件,如果为 false 我会停下来,一切都很好。

不确定我在这里做错了什么。如有任何帮助,我将不胜感激。

谢谢!

乔尼

【问题讨论】:

  • 事实证明,ValidateForm() 函数中实际测试验证的任何内容都不是异步的。根本没有理由在那里使用承诺。这可以只是一个简单的同步函数,它返回表单是否有效。您似乎使这个提议变得比实际需要的困难得多。
  • 嗯.. 你会看看我之前问的这个问题 - 你有什么想法? stackoverflow.com/questions/42989527/…感谢您的宝贵时间。
  • 另外,如果表单有效,我会发布表单。这是我最关心的问题。
  • 是的,您发布了表单,但您没有将其与承诺挂钩,因此承诺没有做任何有用的事情。
  • 对其他问题的接受答案有一个与$.post() 挂钩的ValidateForm()。它使用了promise anti-pattern,因为$.ajax() 已经返回了一个promise,所以不需要将它包装在一个deferred 中。我不完全确定这里的整个问题是什么(包括两个问题中的所有问题)以确切地知道要建议什么。您必须准确描述您要完成的工作,就好像您正在编写一份关于它应该如何工作的规范一样。

标签: javascript jquery ajax promise deferred


【解决方案1】:

您无法异步决定是否要阻止默认操作。当您获得异步结果时,您的函数已经返回并且默认操作已经发生。

如果您必须异步验证,则必须始终阻止默认操作。如果验证成功,那么您将不得不使用 Javascript 手动执行所需的操作。

因此,假设 LoadPartialView_Main() 是您希望在验证成功时发生的情况,您可以执行以下操作:

var DonutsClickEvent = function (e, arg) {
    var url = $(this).attr('data');
    var data = { param: arg };

    if (typeof url === "undefined") return false;

    window.ValidateForm(false).then(function () {
        LoadPartialView_Main(url, data);
    }, function(err){
        // probably show validation error message to the user here
    });  
    // always prevent default action
    return false;
}

此外,没有理由将$.when() 与单个承诺一起使用。你可以使用window.ValidateForm(...).then(...)

【讨论】:

  • 感谢您的回复。是的,我已经返回 false;在'then'之外,但问题是即使验证很好,它也总是会阻止默认操作。我想我可以按照您的建议手动处理活动/非活动状态切换。
  • 只有一个承诺。您可以只使用 window.ValidateForm(...).then(...) - 很高兴知道,谢谢!我按照您的建议做了,始终阻止默认操作 - 当表单验证并成功提交时,我手动触发顶部导航状态更改。我刚刚通过我之前的帖子stackoverflow.com/questions/42989527/… 了解了使用 jquery Deferred、Promise 等。感谢您抽出时间并提供帮助。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2013-06-06
  • 2012-06-19
  • 2022-09-26
相关资源
最近更新 更多