0

2 つの入力テキスト フィールドと 1 つの [保存] ボタンがあります。

<input type="text" id="myInput" />
<input type="text" id="searchResult"/>
<button id="myButton>save</button>

myInputテキスト フィールドにはonchange イベントがあり、Ajax リクエストを送信してデータを取得し、結果をsearchResultテキスト フィールドに表示します。

保存ボタンには、空の文字列などのテキスト フィールドの入力を検証するクリック イベントがあります。searchResultOK の場合は、保存に進みます。

$("myInput").change(function() {
    var userInput = $("myInput").val(); //get value from the text field
    var responseText = callAjaxToGetData(userInput):  //XHR request to get some data

    $("searchResult").val( responseText ); //show the XHR result here

});


$("myButton").click(function() {
    var searchResultField = $("searchResult").val(); //get value from the searchResult field
    var isOK = validate(searchResultField);  //check empty string and such

    if(isOK) { saveDataViaAjax(userInput); }
});

問題

ユーザーがテキスト フィールドにテキストを入力し、"save"ボタンをクリックすると、

  1. onchange eventトリガーされ、callAjaxToGetData()呼び出されます。(XHR)

  2. beforecallAjaxToGetData()が完了し、searchResult テキスト フィールドに入力すると、myButtononclick eventがトリガーされます。

  3. onclick イベント ハンドラー側で、searchResult フィールドがまだ空であるため、検証が失敗します。

  4. callAjaxToGetData()最後に終了し、searchResult テキスト フィールドに入力します。

理想的には、callAjaxToGetData() が最初に完了してから onclick イベント内のプロセスに進み、検証が失敗しないようにします。

これは、人々が直面する非常に一般的なケースのように思われるので、皆さんはこの問題にどのように取り組んでいるのだろうか?

以下のようにonclickイベントに間隔を入れようと考えています(これにはresponseTextがグローバル変数である必要があります)

$("myButton").click(function() {

   var interval = setInterval(function() { //call every 500ms

       //if responseText is not null that means i know the ajax inside of onchange event is completed for sure.
       if( responseText != null ) {

           clearInterval(interval);

           var searchResultField = $("searchResult").val(); //get value from the searchResult field
           var isOK = validate(searchResultField);  //check empty string and such

           if(isOK) { saveDataViaAjax(userInput); }
       }
   }, 500);  
});
4

2 に答える 2

1

以下のコードは正確ではないかもしれませんが、ajax の前にボタンを無効にし、コールバックが返された後に有効にします。

$("myInput").change(function() {
     $("myButton").attr("disabled", "disabled");
     var userInput = $("myInput").val(); //get value from the text field
     var responseText = callAjaxToGetData(userInput, function(data) {

        $("searchResult").val( data); //show the XHR result here
        $("myButton").removeAttr("disabled"); 
     }):
 });
于 2012-06-15T01:27:21.900 に答える
0

onClick eventプロセスがajaxプロセスよりも速くなるのを避けるためにonChange event、タイマーを設定すると問題が解決したと思います。

最初に、アクティブな ajax 接続をチェックし、そうでなければ onClick イベントで呼び出される関数を呼び出すヘルパー関数を作成しました。

ヘルパー

function check_pending_process(callback) {
    var interval = setInterval(function() {
        if($.active > 0) {
            //do nothing here
        }
        else {
            //no ajax is running, call the function after 500 ms
            clearInterval(interval);
            setTimeout(function() { window[callback].call() }, 500);
        }    
    }, 100);
}

発信者

function processButtonClick() {
    var searchResultField = $("searchResult").val(); //get value from the searchResult field
    var isOK = validate(searchResultField);  //check empty string and such

    if(isOK) { saveDataViaAjax(userInput); }

}

$("#myButton").click(function() {

    check_pending_process("processButtonClick");

});

500 ミリ秒の判定は、onchange イベントの post-ajax の処理にかかる時間に基づいています。私の場合、onchange イベント内の ajax 後のプロセスは、応答テキストをテキスト フィールドに入れるだけなので、500 ミリ秒で十分です。

于 2012-06-15T09:04:51.003 に答える