0

背景
这是我的问题的延续设置一系列同步/异步函数的正确方法,所有这些函数都可以停止表单提交和进一步处理?

我得到了正确方法(延迟管道)的答案,但我仍然无法实际实现这一点。我今天才开始阅读 jquery deferred API,但我还不能掌握太多。jQuery API 文档似乎太复杂了,几乎没有例子。任何人都可以提供一些关于此的基本演示/教程的链接吗?我需要在这里启动。

详细信息
我在这个项目中使用了 jquery 1.6 版。

考虑这个例子 - 当用户点击表单提交按钮 -
1. 运行 validateInventory()。
一种。如果验证失败,则向用户显示确认对话框,如果用户同意(转到步骤 2)

b。如果验证通过(转到步骤 2)
2. 运行 preValidateUrls()。
一种。如果验证失败,则向用户显示确认对话框,如果用户同意(转到步骤 3)

b。如果验证通过(转到第 3 步)
3. 提交表单。

以下是我拥有的异步函数的结构 -

请注意,此函数内部还有一个 if(confirm) 块。阅读我的问题 2

    function validateInventory()
    {
         $.ajax({
           type: "POST",
           url: posturl+"?"+params,
           dataType: "json",
           success: function(res)
               { 
                     if(!res.success)
                     {
                          //display some confirmation dialog, if user agrees con
                          if(confirm(msg)) 
                          {
                                //continue with next validation step 
                          }
                     }  
                     else
                     {
                          //validation success - so continue with next validation step
                     }  
                }
            });
    }

    //similar logic as inside validateInventory()
    function preValidateUrls()
    {


    }

我可能在验证逻辑中也有一些同步验证功能(仅限客户端逻辑),在序列中的任何位置 -

function syncVal()
{
    return true/false
}

Question 1 Should the syntax for putting such functions also be similar to the asynchronous functions?

Question 2 How do I handle the display of showing confirmation dialog (if validation fails) and proceed to next validation step only if user confirms. Should there be some restructuring of the function? The if(confirm) block needs to be moved outside?

Where I have reached so far

Well nothing much, I guess I need to use .when, .done APIs.

4

1 回答 1

1

If I understand Steps 1,2,3 correctly, then the logic you want can be coded something like this :

$(function() {
    function validateInventory(form) {//`form` is passed conventionally at the left hand end of the pipe chain.
        var dfrd = $.Deferred();//A Deferred object to be resolved/rejected in response to ajax success/error.
        var params = .....;//use values from `form` as required
        $.ajax({
            type: "POST",
            url: posturl + "?" + params,
            dataType: "json"
        }).done(function(res) {//ajax success
            if(res.success || confirm(msg1)) { dfrd.resolve(form); }//Here we resolve dfrd, passing `form` in order to make `form` available to the next function in the pipe chain.
            else { dfrd.reject("validateInventory() failed (not verified)"); }//Application error. By rejecting with a specific message, we have the means of knowing where the failure occurred.
        }).fail(function(jqXHR, textStatus, errorThrown) {//ajax error
            dfrd.reject("validateInventory() failed (textStatus)");//Again, a specific message.
        });
        return dfrd;
    }

    //Similar logic as inside validateInventory()
    function preValidateUrls(form) {//The form, is piped through by the statement `dfrd.resolve(form);` in validateInventory
        var dfrd = $.Deferred();
        var params = .....;
        $.ajax({
            type: "POST",
            url: posturl + "?" + params,
            dataType: "json"
        }).done(function(res) {
            if(res.success || confirm(msg2)) { dfrd.resolve(form); }
            else { dfrd.reject("preValidateUrls() failed (not verified)"); }
        }).fail(function(jqXHR, textStatus, errorThrown) {
            dfrd.reject("preValidateUrls() failed (textStatus)");
        });
        return dfrd;
    }

    //This is the function to be called if the various stages of validation were successful.
    function overallSuccess(form) {
        form.submit(); 
    }

    //This is a common error handler, which will be called if either of the validation stages fail.
    function errorHandler(message) {
        alert(message);//or whatever
    }

    var myForm = $("form").get(0);//for example

    //And now the glue that puts the component parts together.
    validateInventory(myForm).pipe(preValidateUrls, errorHandler).pipe(overallSuccess, errorHandler);
});

untested

For explanation, see comments in code.

The whole thing can be factored any number of different ways. I would choose to code it as above because the component parts are separate and clear, and the "glue" statement (the pipe chain) is very concise and easy to extend to accommodate further validation steps. With other approaches, you tend to get deep nesting of functions which is hard to follow, especially for someone who has to maintain the code in the future.

于 2012-12-21T14:54:44.747 回答