2011-11-21 103 views
1

我擁有: - 一個名爲'orders'的數據庫表,後者通常由一些java模塊填充。 - 在Grails上運行的網站,顯示這些訂單。更確切地說 - Orders視圖中的list.gsp。 - 如果在瀏覽器上按下刷新按鈕,list.gsp將顯示新訂單。當數據庫表發生變化時,在Grails中自動刷新a .gsp

我需要的是: - 客戶端上的.gsp頁面的某種方式在數據庫上添加新訂單時會自動刷新。 - 當客戶端已經位於.gsp頁面時,autorefresh只需要自動刷新.gsp頁面。即,如果某個客戶在特定訂單的show.gsp上,則不需要自動刷新。

事情我雖然可能會幫助:

  • 選項1:有一個Grails的服務,將定期(每5秒)查詢數據庫,看看是否有任何新訂單。如果有,那麼再次從.gsp頁面再次調用並重新呈現.gsp頁面!

    - suboption1-1: create and destroy a new connection every 5 sec. 
        - suboption1-2: create and keep a connection alive ... forever 
    
  • option2:讓放置訂單的java模塊通過web調用refreshController並以某種方式重新呈現.gsp頁面。即讓RefreshController通知當前位於.gsp頁面的所有客戶端需要刷新。

============================================ ===================================== 跟進:

我該怎麼稱呼控制器從Java腳本?:

function checkDB() 
{ 
    t = setTimeout("com.mypackage.DBChecker.checkdbController.checkAction()", 5000) 
} 

===================================== ============================================= 跟進2:

所以我幾乎得到了我想要的工作,除了我無法弄清楚ow to AJAX回到我的list.gsp頁面只是其本身的一部分。我不想刷新整個頁面,但只有id =「刷新表」的部門。即。

我在此刻下面的代碼不工作:

<script type="text/javascript"> 
     function checkDB() 
     { 
      var xmlhttp; 
      var xmlDoc; 
      var x; 
      if (window.XMLHttpRequest) 
      {// code for IE7+, Firefox, Chrome, Opera, Safari 
       xmlhttp=new XMLHttpRequest(); 
      } 
      else 
      {// code for IE6, IE5 
       xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
      } 

      xmlhttp.onreadystatechange=function() 
       { 
       if (xmlhttp.readyState==4 && xmlhttp.status==200) 
       { 
        xmlDoc=xmlhttp.responseText; 
        x=xmlDoc.getElementsByTagId("refreshTable"); 
        for (i=0;i<x.length;i++) 
        { 
        txt = x[i].childNodes[0].nodeValue; 
        }    
        document.getElementById("refreshTable").innerHTML=txt; 
       } 
       else 
         { 
         } 
       } 

      xmlhttp.open("GET","http://localhost:8080/Orderlord/checkdb/checkdb",true); 
      xmlhttp.send(); 
     } 
     window.load = checkDB(); 
    </script> 

========================== =======================================

跟進3:

我成功地通過複製/粘貼我想要的單獨的gsp的div來通過我的ajax調用返回一個局部頁面。我不知道它是如何工作的 - 這對我來說有點神奇,但是除了當我嘗試對桌子的列進行排序時,一切都有效。然後,只有部分gsp在我的瀏覽器上呈現,而沒有導致最初頁面的其餘部分,在簡單的製表文本頁面中。另外,一旦我結束了這種HTML頁面 - autorefresh不再工作,但只要我將留在checkDB列表視圖中,頁面將每5秒刷新一次。

  1. ...那麼,我該如何解決我的問題

  2. 另一件我不能弄清楚的是如何從控制器返回True/False到gsp中的javascript函數,以及您是如何確切地使用它的?

  3. 最後,我目前在標籤內使用'window.load = timeDB'來調用定時器功能。我嘗試使用,但由於某種原因,無論如何我都無法使它工作。使用時有什麼我應該記住的?

非常最後:我能做些什麼來每5秒刷新一次gsp?

+0

既然你已經有了這麼多,我可以看到有兩種方法可以返回「refreshTable」內容。你可以在你的checkdb控制器中創建一個新的閉包/方法來直接返回表格的html(也許使用groovy HtmlBuilder),或者你可以在你的checkdb控制器中創建一個新的閉包/方法,默認情況下它會轉發(通過命名約定)到只包含你想要返回的div的gsp。在後一種情況下,gsp不一定是完整的html頁面,而只是div部分。 –

+0

後續3張貼以上... –

回答

1

你可以採取的方法setting a timer on the page via javascript。然後,您可以從gsp頁面調用一個輕量級的ajax調用,返回到您的控制器,該調用將產生true/false來指示是否需要完全刷新。這是一個相當簡單的方法,但是您應該小心,ajax調用的後端目標已被優化,因爲每個用戶在該頁面上每5秒會調用一次。它也會產生相當多的流量。

我可能在回到這種方法之前探索早期答案的發佈訂閱插件,但是我已經在中等規模的網站上實現了簡單的定時器/ ajax調用(在java struts世界中),結果相當不錯。

+0

我修改了我的原始問題...請檢查! –

+0

我已經修改了原來的問題了。 –

+0

看到我對以上修改問題的回覆 –

1

你正在解釋的是一個典型的發佈 - 訂閱模型。

grails中有幾個插件可以幫助你做到這一點。看看大氣和彗星爲此。這兩個選項都提供這種pub/sub。

如果他們覺得你想要的東西太重了,你應該簽出Pusher和關聯的Grails插件。它有點更好,因爲您可以將JavaScript庫集成到gsp頁面中,並在創建訂單時從服務器端進行推送。感覺比上面的2個庫輕一些。它使用HTML5網絡套接字。

0

因此,我的list.gsp中的以下代碼爲我做了。我決定每隔5秒刷新一次'div id =「myDiv」'就足夠了,否則我會每5秒鐘打一次服務器,因爲我正在查詢數據庫。

<script type="text/javascript"> 
     function ajaxrefresh() 
     { 
      var xmlhttp; 

      if (window.XMLHttpRequest) 
      {// code for IE7+, Firefox, Chrome, Opera, Safari 
       xmlhttp=new XMLHttpRequest(); 
      } 
      else 
      {// code for IE6, IE5 
       xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
      } 

      xmlhttp.onreadystatechange=function() 
       { 
       if (xmlhttp.readyState==4 && xmlhttp.status==200) 
       { 
       //alert("aaaaaaa")    
       document.getElementById("myDiv").innerHTML=xmlhttp.responseText; 
       } 
       else 
        { 
        //alert("state: "+xmlhttp.readyState) 
        //alert("status: "+xmlhttp.status) 
        } 
       } 

      xmlhttp.open("GET","http://${localHostAddress}:12080/Orderlord/refresh/refreshactiveorders",true); 
      xmlhttp.send(); 

      var t=setTimeout(ajaxrefresh,5000); 
     } 

     window.load = ajaxrefresh(); 
    </script> 
相關問題