浏览器的历史管理

在传统的多页面Web应用程序中,用户通常会使用BACK 或FORWARD 按钮来在多页面间冲浪(surf),并将他

们制作为书签(bookmark)以备日后使用。使用ZK,你仍然可以使用多页面来呈现一套不同的特性及信息,就像在传统的Web应用程序中那样。

但是,对于ZK应用程序来说,在一个桌面内显示很多特性是很平常的,而在传统Web应用程序中则通常需要多个Web页面。为使用户冲浪更简单,ZK支持浏览器的历史管理,ZK应用程序可以简单的在服务器端管理浏览器的历史。

概念很简单。将合适的桌面状态项目(items for appropriate states of a desktop)添加到浏览器的历史中,那么用户可以在同一桌面的不同状态间使用BACK 和FORWARD 按钮冲浪。当用户在这些状态间冲浪时,onBookmarkChanged事件会被发出以通知应用程序。

从应用程序的角度来看,管理浏览器的历史需要两步:

  1. 为桌面每个合适的状态添加一个项目到浏览器的历史。

  2. 监听onBookmarkChanged事件并据此操作朱面。

添加合适的状态到浏览器历史

你的应用程序必须决定把什么合适的状态添加到浏览器历史。例如,在一个多步操作中,每个状态都是一个很好的候选,用以添加到浏览器历史,这样用户可以在这些状态间跳转或将他们制作为书签以备日后使用。

一旦决定了将一个状态添加到浏览器历史,当合适时你可以简单的调用org.zkoss.zk.ui.Desktop接口的setBookmark方法。将一个状态添加到浏览器历史称为bookmarking。注意并不是用户添加到浏览器的书签(亦=IE中我的最爱)。

[提示]: 你可以将在服务器端添加书签成为服务器书签,以区别于浏览器书签。

例如,假定你想当点击Next 按钮时将状态制为书签(bookmark the state),可以按如下方式处理。

<button label="Next" onClick="desktop.setBookmark(&quot;Step-2&quot;)"/>

若你关注URL,会发现ZK为URL添加了#Step-2

若你按下按钮,则会看到,

监听onBookmarkChange事件并据此操作桌面

添加一个状态到浏览器历史后,用户可以在这些状态间冲浪,例如按下BACK按钮返回前一状态。当状态改变时,ZK会通过广播onBookmarkChange事件(org.zkoss.zk.ui.event.BookmarkEvent类的一个实例)到桌面内所有的根组件来通知应用程序。

不同于传统的多页面应用程序,当状态改变时,你必须手动操作ZK桌面。反映展示标签的状态是应用程序开发人员的工作。

为监听onBookmarkChange事件,你可以为桌面内的任何页面添加事件监听器,或任一根组件。

<window onBookmarkChange="goto(event.bookmark)">
   <zscript>
   void goto(String bookmark) {
      if ("Step-2".equals(bookmark)) {
         ...//create components for Step 2
      } else { //empty bookmark
         ...//create components for Step 1
      }
   </zscript>
</window>

就像处理其它的事件,当接收onBookmarkChange事件后,你可以按你想的方式操纵桌面。典型的方法是使用org.zkoss.zk.ui.Executions类的createComponents方法。换言之,你可以使用ZUML页面呈现每个状态,然后当接收onBookmarkChange时, 使用createComponents 在其中创建所有的组件。

if ("Step-2".equals(bookmark)) {
   //1. Remove components, if any, representing the previous state
   try {
      self.getFellow("replacable").detach();
   } catch (ComponentNotFoundException ex) {
      //not created yet
   }

   //2. Creates components belonging to Step 2
   Executions.createComponents("/bk/step2.zul", self, null);
}

iframe使用书签功能

如果一个页面包含一个或多个iframe组件,则有时标记iframe的状态是比较好的选择。例如,当被包含的iframe被转向另一个URL时,你可以改变页面的书签(容器),这样你可以恢复iframe的内容。为了达到这样的效果,你需要监听onURIChange事件,如下。

<window onURIChange="desktop.bookmark = storeURI(event.getTarget(), event.getURI())">
   <iframe src="${uri_depends_on_bookmark}" forward="onURIChange"/>
</window>

一个简单的事例

在这个例子中,我们为没一个tab选项制作一个书签。

<window id="wnd" title="Bookmark Demo" width="400px" border="normal">
   <zscript>
   page.addEventListener("onBookmarkChange",
      new EventListener() {
         public void onEvent(Event event) throws UiException {            try {
               wnd.getFellow(wnd.desktop.bookmark).setSelected(true);
            } catch (ComponentNotFoundException ex) {
               tab1.setSelected(true);
            }
         }
      });
   </zscript>

   <tabbox id="tbox" width="100%" onSelect="desktop.bookmark = self.selectedTab.id">
      <tabs>
         <tab id="tab1" label="Tab 1"/>
         <tab id="tab2" label="Tab 2"/>
         <tab id="tab3" label="Tab 3"/>
      </tabs>
      <tabpanels>
         <tabpanel>This is panel 1</tabpanel>
         <tabpanel>This is panel 2</tabpanel>
         <tabpanel>This is panel 3</tabpanel>
      </tabpanels>
   </tabbox>
</window>