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
}

質問 1そのような関数を配置するための構文も、非同期関数と同様にする必要がありますか?

質問 2 (検証が失敗した場合) 確認ダイアログの表示を処理し、ユーザーが確認した場合にのみ次の検証ステップに進むにはどうすればよいですか。機能の再構築が必要ですか?ブロックを外側に移動するif(confirm)必要がありますか?

今までたどり着いたところ

.when大したことはありませんが、.doneAPIを使用する必要があると思います。

4

1 に答える 1

1

ステップ1、2、3を正しく理解していれば、必要なロジックは次のようにコーディングできます。

$(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);
});

テストされていない

説明については、コード内のコメントを参照してください。

全体は、さまざまな方法で因数分解できます。上記のようにコーディングすることを選択します。これは、コンポーネント パーツが分離されて明確であり、"接着" ステートメント (パイプ チェーン) が非常に簡潔であり、さらなる検証ステップに対応するために簡単に拡張できるためです。他のアプローチでは、特に将来コードを保守する必要がある人にとっては、従うのが難しい関数の深いネストが発生する傾向があります。

于 2012-12-21T14:54:44.747 に答える