2011-11-21 102 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> 
相关问题