Tapestry中的页面定时刷新的两种实现

Tapestry中的页面定时刷新的两种实现
 批量系统原有的页面定时刷新的实现是不太合理的,以RealtimeBatchRunningOfCountwf为例:
 首先在RealtimeBatchRunningOfCountwf.page中定义了属性refreshUrl:<property-specification name="refreshUrl" type="java.lang.String"/>,RealtimeBatchRunningOfCountwf.html中将refreshUrl插入head部分。实现的重点在RealtimeBatchRunningOfCountwf.java中,getRefreshUrl方法返回httpmeta头,在这个头信息中定义了刷新时间和要刷新到的页面的url:
 public String getRefreshUrl() {
  String t_intervalTime = getIntervalTime();
  if (t_intervalTime == null) {
   t_intervalTime = getRequestCycle().getRequestContext()
   .getParameter("intervalTime");
  }
  if (t_intervalTime == null || t_intervalTime.equals("")) {
   return "";
  }
  String url = "";
  
  try{
   url = "<meta http-equiv=\"Refresh\" content=\""
    + t_intervalTime
    + "; URL="
    + getRequestCycle().getRequestContext().getAbsoluteURL(
    "batch-server/app?service=page/RealtimeBatchCountwf")
    + "&gappid=" + getGappid() + "&gfuncid=" + getGfuncid() + "&intervalTime=" + t_intervalTime
    + "&agentzoneno=" + getAgentzoneno()
    + "\"/>";
  } catch(Exception e){
   setMessage(e.getMessage());
   return "";
  }
  return url;
 }
 可以看到getRefreshUrl的实现是非常复杂的,由于TapeStry的页面模型是比较复杂的,其中的变量都是通过页面模型来储存的,如果只是简单的刷新页面,会造成这些页面变量错误,因此在getRefreshUrl方法中将所有的变量拼接到url中,这样在页面的getGappid、getAgentzoneno等方法中首先判断页面请求(getRequestContext)中是否有此页面变量,如果有则取页面请求中的,否则再去取本对象中的变量值。这样看起来getGappid、getAgentzoneno、getRefreshUrl等方法都非常复杂,一旦页面中增加新的属性就需要去修改getRefreshUrl方法,而且这样造成视图(View)的逻辑混杂到了模型(Model)中,违反了MVC的隔离原则,最重要的是这样做违背了Tapestry页面模型设计的原意。因此我做了一个新的实现方法,可以参考BatchTaskContrlwf:
 首先仍然是在BatchTaskContrlwf.java中定义getIntervalTime方法:
 public String getIntervalTime()
 {
  if (intervalTime == null)
  {
   intervalTime = "60";
  }
  setMessage("数据每 " + intervalTime + " 秒更新一次,更新的速度可以在左上角更改");
  return intervalTime;
 }
 getIntervalTime比以前的实现简单了。BatchTaskContrlwf.java中也没有了getRefreshUrl方法,这样保持了视图与模型的独立性。
 在BatchTaskContrlwf.html中body的开头增加如下的javascript:
<script>
 //intervalTime表示秒,但是在setTimeout中的单位是毫秒,所以在后边加三个零
 window.setTimeout("RefreshPage()",<span jwcid="@InsertText" value="ognl:intervalTime"></span>000);
 function RefreshPage()
 {  
  document.getElementById("imgRefresh").click();
 }
</script>
 这里调用定时器实现每隔intervalTime秒就调用一次RefreshPage方法,在RefreshPage方法中则去模拟点击imgRefresh控件,这样就可以达到刷新页面的目的了。imgRefresh是为“刷新”这个图形按钮增加的id属性,因为图形按钮默认是只有name属性的,而且name属性生成的也是随机的,所以为“刷新”按钮增加id属性:
<img jwcid="@ImageSubmit" id="imgRefresh" hspace="20" align="middle" image="ognl:assets.refreshImage" listener="ognl:listeners.refreshAction"/>
 这样就可以在RefreshPage方法中轻松的取得此控件了。
 在RefreshPage方法中也使用getElementById这个技巧,因为Tapestry生成的html中的表单的名称也是不可测的,目前的名称是“$Form0”,但是这个名称是不保障的,如果我们在RefreshPage方法中使用document.$Form0.$ImageSubmit.click()方式刷新页面的话,很有可能在Tapestr实现机制改变或者在页面中加入了新的表单元素后造成代码错误。而getElementById则可以直接根据控件id来定位控件,大大提高了代码的灵活性。
注:上边的文章是我对公司原有产品进行重构的时候发的一篇文章,涉及到了公司的一些私有概念,非公司的人可能读部分章节起来有点费劲,请谅解。如果以后有时间我会整理成通用的文档的。

你可能感兴趣的:(Tapestry中的页面定时刷新的两种实现)