2012-08-16 64 views
1

繼續我的問題,從另一天開始,我遇到了另一件事情,現在我已經花了太多時間敲打我的頭。表單提交與AJAX輪詢呼叫

大部分情況下,我無法讓SUCCESS表單提交。我想這也:

jQuery form submit

下面是一個半功能小提琴代碼:

http://jsfiddle.net/ZcgqV/

本質上發生的事情是這樣的:

  1. 我綁定的方法通過onSubmit(而不是點擊)向表單提交
  2. 提交時,它要求通過jQuery阿賈克斯()的遠程服務器調用
  3. 如果回答是「待定」,重試每1秒,九次
  4. 如果失敗,不提交表單
  5. 成功時,提交表單

無論我嘗試什麼,我都無法讓表單在我想要的時候提交而不進入循環,或者在嘗試遠程服務器時不立即提交。

〜沮喪,試圖-100-的東西 - 即失效-LY你...

下面的代碼直接的情況下,你不喜歡小提琴:

var retries = 0; 
var success = false; 
var token = "toki wartooth is not a bumblebee"; 

$(document).ready(function() { 
    // Attach the action to the form 
    $('#tehForm').attr('onSubmit', 'onsubmit_action(event)'); 
}); 

function async(fn) { 
    setTimeout(fn, 1000); 
} 

function pollServer() { 
    $.ajax({ 
     type: "POST", 
     cache: "false", 
     url: "/remoteCall", 
     dataType: "json", 
     data: { 
      ref_token: token 
     } 
    }).done(function(data, code, jqXHR) { 

     switch (data.status) { 
     case "SUCCESS": 
      alert("Success"); 
      success = true; 

      // --> HERE IS WHERE I WANT THE FORM TO SUBMIT <-- 

      break; 

     case "PENDING": 
      if (retries < 9) { 
       retries += 1; 
       async(function() { 
        pollServer(); 
       }); 
      } else { 
       alert("Failed after 9 tries"); 
      } 
      break; 

     case "ERROR": 
      alert("Error"); 
      break; 

     default: 
      alert("Some kind of horrible error occurred"); 
      break; 
     } 

    }).fail(function(jqXHR, textStatus) { 
     var statusCode = jqXHR.status; 
     alert("Request failed: " + statusCode + " " + textStatus); 
    }); 

} 

function onsubmit_action(event) { 
     pollServer(); 
     if (success === false) { 
      // RETURN FALSE DIDN'T WORK, SO I FOUND THIS 
      event.preventDefault(); 
     } 
}​ 

編輯:

再次,這裏真正的問題是我停止提交表單。在SUCCESS上,我希望提交表格。目前,如果我在SUCCESS中使用.submit(),則會再次調用AJAX,啓動該過程。我想要的只是表單的行動,只有在成功的情況下才能開火。

+0

注意:我知道這是一個看似常見的問題,但我還沒有遇到一個適合我的答案,這就是我問的原因。相信,我一直在閱讀/嘗試。 – Spanky 2012-08-16 23:19:56

+0

我真的不明白你的代碼試圖做什麼,從我可以收集嘗試設置ajax上下文:$('#tehForm');那麼你可以使用$(this)// ==上下文so $(this).submit() – Philip 2012-08-16 23:24:50

+2

是否需要每隔1秒輪詢一次服務器?如果沒有,但你想要快速輪詢,我建議調用一個函數,當你匹配PENDING的情況下,在完成的處理程序中執行另一個Ajax調用。我問的原因是每1秒是真的頻繁,你肯定會從它瘋狂的行爲。將它綁定到完成的處理程序將保證您的瀏覽器可以像瀏覽器一樣快速地觸發調用(並且在大多數情況下,瀏覽器可以同時處理的最大4個Ajax調用似乎不是很有用)。 – brandwaffle 2012-08-16 23:25:43

回答

3

嘗試使用盡可能多的原代碼儘可能的;這裏是一個解決方案:

郵政形式回傳 http://jsfiddle.net/tpm7v/4/

帖子的形式通過Ajax http://jsfiddle.net/tpm7v/5/

var retries = 0, 
    token = "toki wartooth is not a bumblebee", 
    sendRequest, 
    handelResponse, 
    postFormToServer, 
    $theForm = $('#tehForm'); 

$(document).ready(function() { 
    // Attach the action to the form 
    $theForm.bind('submit', onsubmit_action); 
}); 

sendRequest = function() { 
    $.ajax({ 
     type: "POST", 
     cache: "false", 
     url: "/remoteCall", 
     dataType: "json", 
     data: { 
      ref_token: token 
     }, 
     success: handelResponse 
    }); 
}; 

postFormToServer = function() { 
    $.ajax({ 
     type: "POST", 
     cache: "false", 
     url: "/remoteCallToTakFormData", 
     dataType: "json", 
     data: $form.serialize(), 
     success: function() { 
      alert('success!'); 
     } 
    }); 
}; 

handelResponse = function(data, code, jqXHR) { 
    switch (data.status) { 
     case "SUCCESS": 
      postFormToServer(); 
      break; 

     case "PENDING": 
      if (retries < 9) { 
       retries += 1; 
       setTimeout(sendRequest , 1000); 
      } else { 
       alert("Failed after 9 tries"); 
      } 
      break; 

     case "ERROR": 
      alert("Error"); 
      break; 

     default: 
      alert("Some kind of horrible error occurred"); 
      break; 
     } 
}; 

function onsubmit_action(evt) { 
    evt.preventDefault(); 
    sendRequest(); 
} 
​ 
​ 

記住我打算把你提供的代碼。你應該能夠移植這個來和你的實際實現一起工作。您可能還想嘗試諸如https://github.com/webadvanced/takeCommand之類的幫助清理所有Ajax調用。

+0

這應該可行,但我建議還設置一個var,它決定你是否設置了重試計時器,因此你只能調用setTimeout一次。您也可以執行var timer_id = setTimeout(),以便稍後可以在嘗試以9次未成功命中端點後使用clearTimeout()取消超時。 – brandwaffle 2012-08-16 23:51:20

+0

這看起來很有希望,我會在嘗試之後回覆你。謝謝。 – Spanky 2012-08-16 23:51:34

+0

@Spanky讓我知道它是怎麼回事。可能需要調整一些東西才能使其工作。很樂意回答任何問題。 – Paul 2012-08-16 23:53:26

0

請參閱我的評論上面的詳細信息,但我認爲你在這裏看到的問題是這樣的:

每次pollServer()火災,它不僅做一套Ajax調用,但其準備做根據重試循環每秒調用9次可能的ajax。既然你正在用async()方法設置另一個pollServer()調用,你基本上將你的ajax調用混合在一起。你想從你的重試循環中獲得ajax調用,那麼你至少應該只有一秒的請求,而不是1,然後是2,然後是3等等。我可能讀了錯誤的代碼,但這是我最好的猜你在看什麼。

更新:我不確定我的解釋是否清楚,因此我想添加一些其他信息。基本上,每次調用pollServer()並獲得一個PENDING響應時,它都會調用異步,它會註冊一個setTimeout()。 setTimeout()每秒都會繼續運行,執行pollServer(),然後調用異步,它會註冊另一個setTimeout(),它也會每秒運行一次。現在你有兩個函數,每個函數都會調用setTimeout(),假設他們仍然得到PENDING作爲來自服務器的響應。所以在2輪失敗的調用之後,你有4次setTimeout()調用,每次調用一次ajax調用(和一個新的setTimeout)。

+0

謝謝。我沒有看到這種失控/複合行爲。這些電話會像他們應該去的一樣,1s,2s,3s,但是當成功達到時,我無法獲得表格發佈。如果我在以下情況下調用form.submit():SUCCESS,它會重新開始。 – Spanky 2012-08-16 23:33:23

+0

如果我在異步調用中不這樣做,那麼setTimeout根本不起作用,並且所有9次都儘可能快地開火。這是它尊重暫停的唯一方式。請參閱:http://fitzgeraldnick.com/weblog/35/ – Spanky 2012-08-16 23:44:08

0

首先它應該是:$('#tehForm').submit(onsubmit_action);$('#tehForm').on("submit",onsubmit_action);或類似的東西。切勿使用字符串形式傳遞函數。它使用邪惡的eval語句。

接下來,POST後數據已經提交。這是發佈的全部原因。爲什麼需要完成部分中的各種錯誤處理?失敗應該處理錯誤處理。

如果你問有關如何在超時後重試,試試這個: Is it possible to check timeout on jQuery.post()?

我相信超時將陷入失敗。

那麼試試這個:

var retries = 0, 
    max_tries = 9, 
    success = false, 
    token = "toki wartooth is not a bumblebee"; 

$(document).ready(function() { 
    // Attach the action to the form 
    $('#tehForm').on("submit",submit_the_form); 
}); 

function submit_the_form(e){ 
    var dfd = $.ajax({ 
     url : "sendTokenPolling", 
     data : {"token":token}, 
     timeout : 5000 //you may want 1000, but I really think that is too short 
    }); 
    dfd.done(function(){ 
     //success, form posted 
    }); 
    dfd.fail(function(){ 
     //did not work/timedout 
     if (retries < max_tries){ 
     retries += 1; 
     submit_the_form(e); 
     } 
    }); 
} 
+0

帕里斯,我相信OP是在服務器可能響應的情況下,但特定的後端進程可能仍然在運行,這將需要客戶端等待。在這種情況下,失敗方法永遠不會運行,客戶端將不會嘗試重新提交表單。我不相信這個迴應永遠不會超時(至少不是在OP所考慮的'標準'情況下)。 – brandwaffle 2012-08-16 23:44:04

+0

AJAX POST是一個遠程服務器,而不是本地頁面。我將當前表單的活動從遠程調用的響應中解脫出來。 – Spanky 2012-08-16 23:45:22

+0

另外,是的,謝謝,我知道邪惡的東西,這又是一個例子。但是,謝謝,沒有足夠的人認出這一點。 – Spanky 2012-08-16 23:46:25