【问题标题】:Autorefresh a .gsp in Grails when a database table changes当数据库表更改时自动刷新 Grails 中的 .gsp
【发布时间】:2011-11-21 23:21:51
【问题描述】:

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

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

我可能会有所帮助的事情:

  • 选项1:拥有一个定期(每5秒)查询数据库以查看是否有任何新订单的grails服务。如果有,然后以某种方式再次从 .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="refresh table" 的分区。 IE。 。

我目前有以下代码不起作用:

   <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:

通过将我想要的 div 复制/粘贴到单独的 gsp,我成功地通过我的 ajax 调用返回了部分页面。我不知道它是如何工作的 - 这对我来说有点神奇,但一切正常,除了当我尝试对表格的列进行排序时。然后,在我的浏览器上只呈现部分 gsp,而没有初始页面的其余部分,生成一个简单的表格文本页面。同样,一旦我最终进入那种 html 页面 - 自动刷新不再起作用,但只要我留在 checkDB 列表视图中,页面就会每 5 秒刷新一次。

  1. ...那么,我该如何解决我的问题

  2. 我想不通的另一件事是如何将 True/False 从控制器返回到 gsp 中的 javascript 函数,以及您究竟是如何让我使用它的?

  3. 最后,我目前在标签内使用“window.load = timeDB”来调用计时器函数。我尝试使用,但由于某种原因,无论如何我都无法让它工作。使用时有什么需要注意的吗?

最后:我可以做些什么来简单地每 5 秒刷新一次 gsp 的一部分?

【问题讨论】:

  • 现在您已经做到了这一点,我可以看到有两种方法可以只返回“refreshTable”内容。您可以在您的 checkdb 控制器中创建一个新的闭包/方法以直接返回表的 html(可能使用 groovy HtmlBuilder),或者您可以在您的 checkdb 控制器中创建一个新的闭包/方法,默认情况下会转发(通过命名约定)到只包含您要返回的 div 的 gsp。在后一种情况下,gsp 不必是完整的 html 页面,而只是 div 部分。

标签: javascript ajax grails


【解决方案1】:

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

在回退到这种方法之前,我可能会从较早的答案中探索发布订阅插件,但是我已经在一个中等规模的网站上实现了简单的计时器/ajax 调用(在 java struts 世界中),结果非常好。

【讨论】:

  • 我已经修改了我原来的问题...请检查!
  • 我又修改了原来的问题。
  • 查看我对上述修改后问题的回复
  • 对我上面发布的问题的跟进 3
【解决方案2】:

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

grails 中有一些插件可以帮助您做到这一点。为此,请查看 Atmosphere 和 cometD。这两个选项都提供这种发布/订阅。

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

【讨论】:

    【解决方案3】:

    所以我的 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>
    

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-07
      • 2014-06-11
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多