2011-10-26 49 views
3

我正在使用JSF w/Seam的Web應用程序。我希望能夠在每個Ajax響應之後調用JavaScript函數。我正在尋找一種方法來做到這一點,而無需在每個頁面上的每個commandLink/commandButton上放置oncomplete屬性。如何在每個a4j AJAX響應後調用JavaScript函數?

我認爲有一種方法來設置一個servlet過濾器(攔截器?我得到的術語困惑),以注入JS調用到每個響應。我將研究這一點。與此同時,如果有人有任何其他建議,我全都聽過。

編輯:我認爲jQuery ajaxSuccess方法可能是去這裏的方式,但我不知道如何實際使用它。我無法獲得任何註冊。我基本上想添加代碼來獲取來自任何源的任何和所有ajax請求,以在成功時調用我的JavaScript方法。任何人都可以告訴我這樣做的正確方法嗎?我嘗試了很多方法來做到這一點,包括將jQuery("*").ajaxSuccess(function(){myFunction();});添加到我的模板xhtml文件的底部。

回答

4

改寫答案:see original answer in revision history

您可以覆蓋XMLHttpRequest的默認send方法,其中一個劫持readystatechange處理程序:

(function() 
{ 
    var xhrSend = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype.send = function () 
    { 
     var handler = this.onreadystatechange; 
     this.onreadystatechange = function() 
     { 
      if (handler) { 
       if (handler.handleEvent) handler.handleEvent.apply(xhr, arguments); 
       else handler.apply(xhr, arguments); 
      } 
      if (this.readyState == 4) 
      { 
       // your oncomplete function here 
       this.onreadystatechange = handler; 
      } 
     }; 
     xhrSend.apply(this, arguments); 
    }; 
})(); 

編輯:以上函數不使用jQuery的要求工作,所以可能它可能不會與其他庫也是如此。下面的修訂版解決了setTimeout黑客延遲覆蓋處理程序的代碼的問題。當然,使用jQuery,您可以使用全局處理程序,但對於具有類似行爲的其他庫,這將會很有用。

(function() { 
    function globalHandler() { 
     if (this.readyState == 4) { 
      // your oncomplete code here 
     } 
    } 
    var xhrSend = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype.send = function() { 
     var xhr = this; 
     if (xhr.addEventListener) { 
      xhr.removeEventListener("readystatechange", globalHandler); 
      xhr.addEventListener("readystatechange", globalHandler, false); 
     } 
     else { 
      function readyStateChange() { 
       if (handler) { 
        if (handler.handleEvent) 
         handler.handleEvent.apply(xhr, arguments); 
        else 
         handler.apply(xhr, arguments); 
       } 
       globalHandler.apply(xhr, arguments); 
       setReadyStateChange(); 
      } 
      function setReadyStateChange() { 
       setTimeout(function() { 
        if (xhr.onreadystatechange != readyStateChange) { 
         handler = xhr.onreadystatechange; 
         xhr.onreadystatechange = readyStateChange; 
        } 
       }, 1); 
      } 
      var handler; 
      setReadyStateChange(); 
     } 
     xhrSend.apply(xhr, arguments); 
    }; 
})(); 

http://jsfiddle.net/gilly3/FuacA/5/
我在IE7-9進行了測試,Chrome瀏覽器的最新版本和FF

+0

我也嘗試過。仍然沒有效果。問題是我的ajax請求不是通過jQuery完成的嗎? – iandisme

+0

@iandisme - YES !!絕對!那是你的問題。 '.ajaxSuccess'是一個* jQuery事件*。如果您在jQuery之外製作常規的XMLHttpRequest,jQuery無法瞭解它。 – gilly3

+0

@iandisme - 查看我的非jQuery解決方案的更新答案。 – gilly3

1

我認爲這是你在找什麼:Using Global Ajax Handlers In jQuery

+0

也不能得到這個工作。 jQuery(「*」)。bind(「ajaxSuccess」,function(){myFunction();});而其他一些東西根本不起作用。 – iandisme

+0

和爲什麼不工作? –

+0

鏈接不起作用(至少今天[2013年7月10日]該網站不可用)。 – matt

3

由於您使用RichFaces的,你可以簡單地使用:

<a:status id="globalStatus" onstart="onRequestStart()" onstop="onRequestEnd()" /> 
+0

這不適合我。通過文檔,有一個「for」屬性指向我需要指定的a4j輸出區域。簡單地將此添加到我的模板文檔中的主窗體中並不能解決問題。 +1雖然介紹我的標籤。 – iandisme

+0

只是我的記憶:我認爲這對我有用,因爲我們定義了一個全局的ajax隊列。如果你有這樣的隊列,那麼這應該工作。否則,您可以在for屬性中定義隊列名稱,或者也可以在ajax按鈕的id中定義隊列名稱。我會爲此查看Richfaces的現場演示。 –

+0

我使用全局ajax隊列,以避免着名的併發呼叫對話問題,因爲你沒有定義一個但我不知道你不使用對話或解決它不同? –

2

使用A4J:狀態應該工作,但它必須是一個H內部:表單標籤:

<h:form id="randomForm" styleClass="edit"> 
     <a:status id="stateStatus" 
     onstart="Richfaces.showModalPanel('waitBx'),document.getElementById('randomForm:search').disabled=true;" 
     onstop="Richfaces.hideModalPanel('waitBx'),document.getElementById('randomForm:search').disabled=false;" 
     styleClass="message" > 
</a:status> 

...... way more code 
</form> 

每次ajax調用後,彈出一個等待圖片並禁用搜索按鈕。

有趣的是,至少在我們的代碼中,這不適用於任何嵌套的a4j:區域。

+0

+1表示重要的表單標記 –

相關問題