数据库表更改时,在Grails中自动刷新.gsp

时间:2011-11-21 23:21:52

标签: javascript ajax grails

我拥有的:   - 一个名为“orders”的数据库表,后端不断填充某些java模块。   - 在Grails上运行的网站,显示这些订单。更准确地说 - 订单视图中的list.gsp。   - 如果在浏览器上按下刷新按钮,list.gsp将显示新订单。

我需要什么:   - 在数据库上放置新订单时,客户端上的.gsp页面会自动刷新的某种方式。   - 当客户端已经在.gsp页面时,autorefresh只需要自动刷新.gsp页面。即如果客户在特定订单的show.gsp上,则不需要autorefresh。

我可能会帮助的事情:

  • 选项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:

所以我几乎得到了我想要的工作,除了我无法弄清楚如何将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'来调用计时器功能。我尝试过使用,但出于某种原因,无论如何我都无法工作。使用时有什么我应该记住的吗?

  4. 最后:我怎么做才能每5秒刷一次gsp的一部分?

3 个答案:

答案 0 :(得分:1)

您要解释的是典型的发布 - 订阅模型。

grails中有一些插件可以帮助你做到这一点。看看Atmosphere和cometD吧。这两个选项都提供了这种pub / sub。

如果他们觉得你想要的东西有点太重,你应该结帐Pusher和相关的Grails插件。它更好一点,因为你可以在你的gsp页面中集成一个javascript库,并在创建订单时从服务器端进行推送。感觉比上面的2个库略轻。它使用HTML5网络套接字。

答案 1 :(得分:1)

您可以采用setting a timer on the page via javascript的方法。然后,您将从gsp页面调用轻量级ajax调用回到控制器,该调用将产生true / false以指示是否需要完全刷新。这是一种相当简单的方法,但您需要注意ajax调用的后端目标已经过优化,因为该页面上的每个用户每5秒钟会调用一次。它还会产生相当多的流量。

我可以在回到这种方法之前从早期的答案中探索发布订阅插件,但是我已经在一个中等大小的网站上实现了简单的timer / ajax调用(在java struts世界中),效果非常好。

答案 2 :(得分: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>