2012-06-15 64 views
0

我有兩個輸入文本字段和一個「保存」按鈕。設置間隔的方式來確保Ajax調用完成?

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

myInput文本字段onchange事件然後發送Ajax請求得到一些數據,並顯示結果searchResult文本字段。

保存按鈕有單擊事件它驗證輸入searchResult文本字段爲空字符串等。如果可以,繼續保存。

$("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. 之前callAjaxToGetData()是填寫並填寫searchResult文本字段,觸發myButton onclick 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); 
}); 
+0

點擊保存後,您檢查一個請求是否正在進行並等待它完成,然後調用validate-save函數。另一個問題可能是如果你改變輸入速度太快,並且請求進入競爭狀態,所以你必須停止第一個或忽略它。 – jasssonpet

+0

$ .active可以作爲一個選項。 –

回答

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"); 
    }): 
}); 
+0

您的意思是「myButton」的點擊事件會在「myButton」中刪除禁用屬性後立即觸發?如果是這樣,我不知道事件觸發時間可以通過這種方式進行控制。 –

+0

我試過上面的代碼,並且由於按鈕被禁用,所以click事件不會在更改事件後觸發。 –

+0

嘿,上面的代碼會禁用按鈕,直到收到數據。然後該按鈕重新啓用。 (因爲在通話返回之前按下按鈕並不是一個真正有效的選項。)我希望這有幫助。 – DanielEli

0

我認爲,爲了避免onClick event過程進行中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事件過程需要多長時間。在我的情況下,在onchange事件中的後ajax進程只是將響應文本放入文本字​​段,所以500毫秒就足夠了。