实例 XPages 开发一个通用的 Dojo Tree 风格定制控件

作者:詹 永华,软件工程师,IBM中国软件开发中心 WPLC
杨 志磊, 高级软件工程师, IBM 中国软件开发中心 WPLC
张 世佳, 软件工程师, IBM 中国软件开发中心 WPLC

本文详细介绍了如何使用 Lotus®DominoDesigner 8.5 中的 XPages 开发一个通用的 Tree View 风格定制控件,用来展现 Domino 视图的层次结构。通过本文,读者可以应用新一代的XPages技术,在基于 Domino 的 Web 应用中开发灵活、可复用的用户定制控件,并且能够了解 XPages 是如何方便地应用Dojo 工具包和 JavaScript. 类库。

背景简介

这个部分将会对本文中所使用的相关技术做简要的介绍。读者如需了解更详细的内容,可以访问 IBM 或相关组织的网站。

Lotus软件试用下载

立即下载最新版本的 IBM Lotus Notes 和 Domino 试用软件,尝试利用 XPage 技术开发第一个 Domino Web 2.0 应用程序。

XPages:Domino 8.5 强大的 Web 设计元素

XPages 是 IBM Lotus Domino 8.5 中新增的一个功能强大的设计元素,可以充分利用它为我们的项目呈现 Web 客户端用户界面。XPages 利用一种新的 JSF(JavaServerFace) 呈现引擎,与传统的 Domino Web 开发相比较,XPages 无疑是一个强大的 Web 设计元素。

Domino 8.5 为用户提供了集成 Eclipse IDE 的可视化开发环境。使用 XPages 开发基于 Domino 的 Web 应用,可以获得“所见即所得”的用户体验。对 XPages 中的每一个页面、控件、对象,我们都可以直接以可视化的方式修改它们的属性,并且即时预览;相应的,对象所支持的事件,XPages 也提供了分门别类的向导,帮助用户编辑和管理事件的响应脚本。

XPages 更大的优势体现在对 Domino数据库的数据绑定。我们可以为每一个页面或者内嵌面板创建一个“数据源”,这个数据源可以是 Domino 数据库的一个文档或视图。然后,通过简单的操作就可以将数据源中的数据,如文档域值,动态绑定到 Web 页面的对象上。当然,通过编写脚本,我们还可以对数据计算处理之后再将其与页面元素绑定。

不仅仅是这样,对于习惯了开发 Agent 来操作 Domino 数据的用户来说,XPages 提供了灵活的可编程性和可扩展性。用户可以通过集成的 Eclipse IDE 开发自己的 Java 函数库,然后使用 XPages 支持的服务器端 JavaScript. 来调用这些 Java 函数,为客户端生成用户想要的数据。

在本文中,我们介绍了如何应用 XPages 和 Domino 包含的 Dojo 1.1.1 工具包开发一个通用的 XPages 定制控件,使用 Dojo 的 Tree Widget 来展现传统 Domino 视图的层次关系。在介绍方法的过程中,相信用户可以领略到前述 XPages 的强大功能和灵活性。

Domino 视图

Domino 视图是文档集合的列表,它丰富的层次结构和表现力使它成为 Domino 数据库浏览的强大工具。与文档一样,Domino 视图既支持 Notes 客户端的访问方式,也支持 Web 浏览方式。(在 Designer 中打开“视图 > AllExpences”,在工具栏中选择“在 Web 浏览器中预览”。)缺省的 Web 视图已经远不能满足 Web 2.0 用户的需求。更不方便的是,它的数据源和页面格式完全决定于数据库中已有的视图, 用户不能做灵活定制。于是很多 Domino Web 应用开发人员都会选择开发自己的 Web 视图,在传统的 Domino Web 开发中,这并不是一件容易的事情。

Dojo 和 dijit.Tree

Domino 中提供了 Dojo 工具包,可以在服务器的(C:\IBM\Lotus)\Domino\data\domino\js\ 目录下找到它。在 XPages 中使用 Dojo toolkit,我们可以轻松地为 XPage 页面加入 Web 2.0 元素,如 Widget、动画等等。

Dojo 是一个强大的面向对象、开源的 JavaScript. 工具库。Dojo 为 Web 应用的开发提供了大量基于 DHTML、CSS 和 JavaScript. 等技术的客户端组件。Dojo 项目开发的最初目标是解决开发 DHTML 应用程序遇到的那些长期存在的历史问题。 如:跨浏览器问题。所以使用 Dojo,更容易使您的 Web 页面具有动态能力,或在任何稳健的支持 JavaScript. 语言的环境中发挥作用。而 Dojo 在代码质量、运行性能以及文档支持等方面在同类的开发项目中都可说是首屈一指。本文中将会应用的 dijit.Tree 对象就是 Dojo 中用来显示树状层次结构的 Widget。它使用的数据源是 JSON 格式的数据。

JSON

JSON(JavaScript. Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于 JavaScript. 的一个子集。

JSON 对象是一个无序的“‘名称 / 值’对”集合。一个对象以“{”开始,以“}”结束。每个“名称”后跟一个“:”,“‘名称 / 值’对”之间使用“,”分隔。JSON 数组是值(value)的有序集合。一个数组以“[”开始,“]”结束。值之间使用“,”分隔。JSON 值(value)可以是双引号括起来的字符串(String)、数值 (number)、true、false、null、对象 (object) 或者数组 (array)。这些结构是可以嵌套的。

系统框架和方法

在开始所有的步骤之前,我们有必要先总体介绍一下本章中涉及的 XPages 元素和它们的关系。如服务器端 / 客户端 JavaScript、Java 类、CSS 的开发和使用等等。

图 1,服务器端的 Domino 数据库设计元素和客户端 Web 页面运行时的元素被列举了出来。XPage 页面中的 DIV 对象将被解析成客户端的 Dojo 对象。由图示,我们也可以清楚地看到关于它的数据(1),动作(2)和外观(3)的定义。


图 1. 系统框架
图 1. 系统框架

Dojo 对象

在 XPage 页面中,我们定义一个 DIV 映射相应的 Dojo 对象。主要有两种方法可以将 DIV 和 Dojo 对象进行绑定。

其一,在 DIV 中直接使用‘ dojotype ’属性定义 Dojo 对象类型,如下例定义了一个 dijit.Tree 对象,也就是我们通常说的 Dojo Tree Widget。


清单 1. 定义 dojo 对象

<divdojoType="dijit.Tree"id="mytree" model="continentModel" showRoot="false"></div>

其二,在 XPges 页面中指定 DIV 的 id,然后使用客户端 JavaScript. 在页面加载时通过对象 id 实现动态绑定,如下例将一个 jox.charting.Chart2D 对象绑定到了一个 DIV 对象上。


清单 2. 动态绑定 dojo 对象

<!--XPage 页面 --> 
<div id="piechart" style="width: 250px; height: 250px;"></div> 
<!-- 客户端 JavaScript--> 
var chart1 = new dojox.charting.Chart2D("piechart")

细心的读者可能发现了在上面的两个例子中,我们都直接使用了 HTML 的 <DIV> 标签,而没有使用 XPages 中的 <XP :DIV> 标签。这并不是个随意的选择。对第一种方法,我们使用了 ‘ dojotype ’属性,该属性是 <DIV> 标签接受的属性定义, 但却不是 <XP :DIV> 标签接受的属性定义,XPage 页面中将会出现错误提示;对第二种方法,如果我们使用 <XP :DIV> 标签的话,XPages 引擎将会把它的 id 属性值解析成类似 view:_id1:_id2:piechart 的形式, 这样在动态绑定阶段 Dojo 将因为无法找到 id 为 piechart 的对象而绑定失败。有兴趣的用户可以自己尝试一下这两种情况的结果,加深对 XPages 中 HTML 标签和 XPage 标签的理解。

所以,当在 XPage 页面中加入 Dojo 对象时,请务必使用 HTML 标签。

数据

本例中的数据来源于 Domino 视图,除此之外,数据也可以来源于 Domino 的文档或者其它的关系型数据库。图 1中图示(1)标明的路线是我们应用 Domino 视图数据的方式:用 Java 类读取 Domino 视图数据,并将数据构造为 Dojo 对象 JSON Schema 要求的格式; 再用服务器端 JavaScript. 调用 Java 类方法获得这些数据,并将它存储在 XPage 页面的客户端 JavaScript. 变量中。

动作

图 1中图示(2)标明了 Dojo 对象动作响应的客户端 JavaScript. 的来源:Dojo 包中的针对该对象的和用户自定义的客户端 JavaScript。在实际的应用中,用户通常是通过编写客户端的 JavaScript,来为 Dojo 对象支持的客户端用户事件,如onClickonChange等加入动作响应的。

外观

图 1中图示(3)标明了决定 Dojo 对象外观格式的来源:Dojo 包中关于对象外观的定义和用户自定义的 CSS。为了改变 Dojo 定义的缺省外观显示格式,用户需要通过“重载”的方式重新定义该对象的 CSS 类文件。

使用 Dojo Tree 展示 Domino 视图

本文的第 3 部分,将详细说明我们是如何从 Domino 数据库中提取数据,并且将数据与 Tree 视图显示绑定起来的。让我们遵循图 2实例流程图的步骤来构建一个 Dojo Tree Widget 的用户定制控件吧。


图 2. 流程图(查看大图
图 2. 流程图

获取 Domino 视图 JSON 数据

Domino 视图拥有自己的 JSON 数据,利用 URL 命令参数,我们可以查看 Domino 视图的 JSON 数据。对一个可以从 Web 浏览的 Domino 视图,只需在浏览器 URL 的最后面添加参数“?ReadViewEntries&outputformat=JSON”,就可以看到它的 JSON 格式。

但是,Domino 视图的 JSON 数据与 Dojo Tree 的 JSON Schema 并不一致,所以我们无法直接地使用 Domino 视图 JSON 数据作为 Dojo Tree 对象的数据来源。下图的 Domino 视图 JSON 格式如图 3(a),如果要构造 Dojo tree,却需要如图 3(b) 格式的 JSON。


图 3. Domino 视图 JSON 和 Dojo tree JSON
图 3. Domino 视图 JSON 和 Dojo tree JSON

我们可以使用 Java 类和服务器端的 JavaScript. 来实现这两种不同 JSON 格式的转换。

首先,创建 Java 类获取 Domino 视图数据。Domino Designer 8.5 基于 Eclipse 平台,可以很方便的创建 Java 类。我们通过“窗口 > 打开透视图 > Java”选择 Java 视窗。

在右侧选择自己的项目 tree.nsf,在项目下创建相关的 Java 类文件。本例中,我们创建了两个类TreeNodeOrganJSON,具体代码可以参见本文后的附录。其中,OrganJSON类中的getOrganTree方法实现的功能是将 Domino 的视图层次转化为树结构,并且返回类型为TreeNode的根节点,通过树的的根节点,我们可以遍历树中所有的节点;getTreeJSON 方法实现则是由树的根节点开始做遍历,并最终生成 Dojo Tree 能够识别的 JSON 格式的字符串。

然后我们在 Designer 中创建一个服务器端的 JavaScript. 用于调用刚才创建的 Java 类中的方法。我们通过“窗口 > 打开透视图 > Domino Designer”回到 Designer 的工作区。在“代码 -> Script. 库”中选择“新建服务器 JavaScript. 库”,创建 Tree.jss 文件。在这个文件中,创建了getJsonString函数,在该方法中,我们需要传入 Domino 的视图名字和视图中一个列的名字,这个列的名字用于在树状结构中显示,在本示例中可以选择 name 列,也可以选择 email 列。


清单 3. JavaScript. getTreeJSON 函数

function getJsonString(view, column){ 
    var viewName:String = view; 
    var columnName:String = column; 
    var organJSON:com.ibm.test.tree.OrganJSON =new com.ibm.test.tree.OrganJSON(); 
    var organTree:com.ibm.test.tree.TreeNode = organJSON.getOrganTree(session, 
        "tree.nsf", viewName, columnName); 
    var rganTreeStr=organJSON.getTreeJSON(organTree); 
    return organTreeStr; 
}

绑定 Domino 视图数据

接下来需要在 XPage 页面中添加 Dojo 的数据源,我们通过一个计算域来实现,代码如下:


清单 4. JavaScript. 用计算域获取服务器端数据

<xp:text escape="false" id="computedField1"> 
    <xp:this.value> 
        <![CDATA[#{javascript.:var viewName = compositeData.ViewName; 
        var columnName = compositeData.ColumnName; 
        var json = getJsonString(viewName, columnName); 
        var result = "<script. language=\"JavaScript\" type=\"text/javascript\">"
        result += "var jsonStore = new dojo.data.ItemFileReadStore({data:" + json + "});"
        result += "</script>"
        return result;}]]> 
    </xp:this.value> 
</xp:text>

我们首先得到传入用户定制控件的属性ViewNameColumnName(有关用户定制控件和属性的说明,参照第 4 部分),然后通过调用我们之前创建的服务器端的 JavaScript. 中的方法json=getJsonString(viewName, columnName);来生成 JSON 格式的数据源。

有了 JSON 的数据源,接下来我们只需要在控件页面中利用 Dojo Tree 提供的相关 API 就可以将我们的树状结构展示出来了。在源中加入以下标准的 HTML 代码。其中store="jsonStore"是我们在前面的计算域中定义过的 jsonStore,也就是本示例中用到的数据源。query="{name:'0'}"是我们从数据源 jsonStore 中读取的根节点,将其作为树状结构的根元素。<Script>是添加在树叶节点上的动作,当点击叶子节点是出现一个 alert 对话框,显示所选节点的标签内容。


清单 5. XPage 中的 Dojo 对象

<div dojoType="dijit.tree.ForestStoreModel"
    jsId="continentModel" store="jsonStore" query="{name:'0'}"> 
</div> 

<div dojoType="dijit.Tree" id="mytree" model="continentModel"
    howRoot="false" penOnClick="true"> 
    <script. type="dojo/method" event="onClick" args="item"> 
        alert("Execute of node " + jsonStore.getLabel(item) +", 
        population=" + jsonStore.getValue(item, "population")); 
    </script>
</div>

创建用户定制控件

创建用户定制控件

在 XPages 中,用户定制控件是一个允许用户定义、编辑,并且在不同的 XPage 页面中复用的组件。它类似于 Domino 模板设计中的“子模板”,或者 Web 页面设计中的面板。不同的是,它提供了更为强大的功能和可定制性。如,支持用户以拖拽的方式直接将 XPages 的“核心控件”组合在一起;支持用户自定义的控件属性;管理并支持用户以拖拽和定制的方式复用控件。如果用户开发的 Web 应用中有一些部分是会被反复使用的,比如 Header, Menu bar, Navigator,或者就如我们正在创建的展示 Domino View 层次结构的通用 Dojo Tree,那么创建一个可复用的“定制控件”是最好的选择。

通过右键“控件”选择“新建定制控件”ccTree,如图 4。在工作区中,我们可以在“设计”和“源码”两个页面中编辑它。在工作区下面,可以看到控件的属性、事件。图的右下角,在定制控件管理面板中,ccTree 被列在里面,当要创建其它的 Xpage 页面或者其他的定制控件时,我们都可以直接通过把它拖入工作区复用它。也就是说,定制控件是支持嵌套的。

定制控件还允许用户自定义属性,使用它时,通过传入不同的属性值就可以实现对它的定制。而图中的 ViewName 和 ColumnName 正是我们为 ccTree 定义的属性。ViewName 代表了希望展示的 Domino 视图的名字,ColumnName 代表了用于在树状结构中显示的列的名字。


图 4. ccTree 用户定制控件
图 4. ccTree 用户定制控件

为了在 XPages 中使用 Dojo Tree 元素,需要将用到的 Dojo 包引入到控件中,通过“属性 > 资源 > 添加脚本库”按钮,添加将要用到的dojo.parserdojodataItemFileReadStoredijit.Tree包。也可以选择通过直接编辑源码实现。


清单 6. XPage 中加入资源
<xp:this.resources> 
    <xp:dojoModule name="dojo.data.ItemFileReadStore"></xp:dojoModule> 
    <xp:dojoModule name="dojo.parser"></xp:dojoModule> 
    <xp:dojoModule name="dijit.Tree"></xp:dojoModule> 
</xp:this.resources>

同时,为了能使用我们之前定义的 JavaScript. 库,也需要把它引入到控件中,同样通过“属性 > 资源 > 添加脚本库”来实现。当然,也可以选择通过直接在源码的<xp:this.resources>里加入<xp:script. src="/Tree.jss" clientSide="false"></xp:script>语句来实现。

ccTree 用户定制控件的文件内容请参照附件。

在 XPages 中复用控件 ccTree

我们创建的定制控件 ccTree 现在已经可以使用了。让我们看看使用它是多么方便和灵活吧!

我们需要做的仅仅是:

  1. 新建一个 XPage 页面。
  2. 将 ccTree 控件从定制控件面板中拖入工作区(需要切换到“设计”页才可实现拖拽)。
  3. 传入参数。切换到“源码”页,找到控件的位置,加入 Domino 视图名字和需要显示的列名字。代码如下,在本例中的数据库 tree.nsf 中,有一个名叫 Contacts 的视图显示了联系人列表,其中 Name 列是联系人的名称。
    <xc:ccTree ViewName="Contacts" ColumnName="Name"></xc:ccTree>

之后,预览这个 XPage 页面,就能看到如图 5(b)的 Dojo Tree 树状图,展现了 Contacts 视图的层次结构,在叶节点上显示的是联系人名称。就本例而言,如果您想让叶节点上显示联系人的邮件地址,很简单!在上述的代码中将 ColumnName 的值设为 Email;如果您想显示别的视图,也很简单,修改上述代码中的 ViewName 和 ColumnName 值就可以了。

示例效果展示

为了使读者能够更直观地了解本文实现的 Dojo Tree 定制控件,我们给出了如图 1的实例效果图。图 5(a), 是 Domino 缺省支持的 Web 视图;图 5(b),是利用本文提供的定制控件,在 XPages 中生成的 Dojo Tree 风格的视图层次。这样的 Web 页面更符合 Web 2.0 用户的使用习惯。更重要的是,它以 XPages 定制控件的形式提供给用户,非常易于复用和定制,可以很方便地复用在任何 XPage 页面中,通过传入少量参数即可用来显示任何 Domino 视图。


图 5. 实例:用 Dojo Tree 显示联系人列表
图 5. 实例 : 用 Dojo Tree 显示联系人列表

如何使用本文中的源文件

本文主要用到的源文件。包括 :

  1. Java 函数库、Java 类文件:OrganJSON.java,TreeNode.java
  2. 服务器端 JavaScript. 函数库:Tree.jss (代码 > Script. 库 > Tree)
  3. 定制控件:ccTree (定制控件 > ccTree)

如何应用这些源文件:

  1. 打开 Domino Designer 8.5,新建一个数据库 tree.nsf(如果要在 Designer 中预览,需要将 tree.nsf 拷贝到 Notes 的 Data 目录中)。
  2. 切换到 Java 透视图,将 Java 类文件 OrganJSON.java、TreeNode.java 拷贝到 tree.nsf 工程目录中。
  3. 切换回 Desinger 工作区,定制控件 ccTree 和 JavaScript. 函数库 Tree.jss 拷贝到您的数据库中。
  4. 在您数据库中需要加入 ccTree 控件的 XPage 页面中按照第 4.2 节生成“XPage 页面”的方法加入 ccTree 控件,并配置它的参数,用来显示您数据库中已有的 Domino 视图。
  5. 选择“设计 > 在 Web 浏览器中预览” 。

布署到 Domino Server 上浏览:

  1. 将 tree.nsf 拷贝到 Domino Server 的 Data 目录中。
  2. 从浏览器中访问 http://(dominoserver host)/tree.nsf/Tree.xsp。

    结束语

    本文通过一个实例详细介绍了如何使用 XPages 开发一个通用的 Dojo Tree 风格定制控件,用来展现 Domino 视图的层次结构。通过本文,读者应用 XPages 技术,在基于 Domino 的 Web 应用中开发灵活的、可复用的用户定制控件,并且使用和集成 Dojo 的 JavaScript. 类库。

posted @ 2010-12-08 10:07  hannover  阅读(2718)  评论(1编辑  收藏  举报