以列表形式显示大量数据是各种开发中最常见和基本的需求之一。在数据保存在关系型数据库的Web开发中,程序员要处理的是分开的两项任务,一是从数据库中查询记录,二是在视图层生成显示这些数据的HTML。如何分页是主要问题。Domino以界面为导向的开发风格和不适于动态查询的文档型数据库使得程序员面临完全不同的处境和问题。预先设计的视图不仅定义了包含的文档,也设置了外观属性,集数据层和外观层的功能于一体。在客户机中,视图拥有和设计时同样的外观,无需编程。在Web端,因为Domino默认生成的视图HTML过于简陋,程序员还是需要各种各样的方法改进其外观和操作性。下面就胪列了我曾经接触和使用过的Domino视图Web展现技术,并做了简单分析和评价。
1. 使用Domino生成的HTML
优点:
- 无需编程。
缺点:
- 显示原始简陋。
2. 使用Applet
优点:
- 无需编程。
- 操作与客户端一致。
缺点:
Applet的所有缺点,包括:
- 用户所在机器需安装Java运行时,虽然目前大部分机器都已安装。
- 需要下载和载入Applet,速度较慢。
- 与网页整体风格不一致。
- IBM早已放弃其更新,实际上自Java7 Update 51起因为没有提供Java运行时要求的权限属性(Permission Attribute)Domino自带的Applet都无法在浏览器里运行。
3. 将视图内容显示为HTML
这种方法需要在视图的列公式内计算产生最终的HTML。
优点:
- 可以精细地自定义显示的内容。
缺点:
- 笨拙繁琐,难以维护。
- 该视图只能用于Web显示,无法通用于客户端显示和后台查询。
- 列中的大量HTML计算,对视图索引的速度和大小都有负面影响。
4. 在视图原始HTML载入后用JavaScript调整修饰
Domino早期Web开发中常使用的方法,在显示视图的页面的onload事件里运行一段脚本,修改视图原始的HTML。Domino产生的视图HTML原始、丑陋、古怪且总不改进,使用这种方法需要透彻了解这些HTML的细节。
优点:
- 能够完全自定义视图的展示,将其修改成任何所需的外观。
- 脚本写得足够灵活的话,还能配合代理获取视图的外观属性以设置列宽度、标题等,无需手工输入参数。
缺点:
- 需要JavaScript开发(可写成适用于所有视图的通用函数,只需一次开发),并且对HTML的修改无逻辑可理解,只能根据Domino生成的HTML硬编码。例如下面的片段:
//1、删除标题行最后一个单元格 //strDiv = strDiv.replace(/<TH><\/TH><\/TR>/g,"</TR>"); //2、删除分类行最后一个单元格 //strDiv = strDiv.replace(/<TD><\/TD><\/TR>/g,"</TR>"); //3、删除各内容行最后一个单元格 //strDiv = strDiv.replace(/<TD><IMG alt="" border=0 height=16 src="\/icons\/ecblank\.gif" width=1><\/TD><\/TR>/g,"</TR>");
代码难于理解和维护。
- 一旦Domino修改视图生成的HTML,就需要重新观察并相应调整代码。
- 页面载入时可能会先显示原始视图,经过脚本运行的延时后才显示调整后的视图。
5. 使用JavaScript读取视图内容的XML或JSON
这种思路是Domino视图Web展示上的一大突破,在readviewentriesURL命令下Domino服务器发送到浏览器的只有视图的内容数据,不包含字体、颜色等任何外观信息,读取它以生成显示视图的HTML完全依赖JavaScript脚本和CSS。这些前端文件构成独立的视图层,因而具有前所未有的最大的灵活性。在XPages出现之前,这种方法已经为许多公司和开源代码所使用。
优点:
- 具备第四种方法的所有优点,而没有它大部分缺点。
- 能在一个页面上加载多个视图。
缺点:
- 需要JavaScript开发,要掌握相关的XML知识和理解readviewentries产生的数据格式。
6. 使用XSLT技术转换视图的XML数据
我在接触到上一种方法后想到,既然可以获得视图的XML数据,那应该也能用XML技术家族内的XSLT来将此XML转换成用于显示的HTML。下面就是我当时的试验代码和显示效果:
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method=‘html‘ version=‘1.0‘ encoding=‘UTF-8‘ indent=‘yes‘/> <xsl:template match="/"> <h2>View XSLT</h2> <table > <tr><th>Number</th><th>Who</th><th>Date</th><th>Time</th><th>Size</th><th>Subject</th></tr> <xsl:for-each select="viewentries/viewentry"> <xsl:variable name="unid"> <xsl:value-of select="@unid" /> </xsl:variable> <xsl:variable name="linemod2" select="(number(@position) mod 2)"> </xsl:variable> <xsl:variable name="lineHtml"> <td><xsl:value-of select="@position" /></td> <td><xsl:value-of select="entrydata[@columnnumber=‘2‘]"/></td> <td><xsl:value-of select="entrydata[@name=‘$70‘]"/></td> <td><xsl:value-of select="entrydata[@name=‘$99‘]"/></td> <td><xsl:value-of select="entrydata[@name=‘$106‘]"/></td> <td><a href="{$unid}"><xsl:value-of select="entrydata[@name=‘$73‘]"/></a></td> </xsl:variable> <xsl:choose> <xsl:when test="$linemod2=1"> <tr class="oddLine"><xsl:copy-of select="$lineHtml" /></tr> </xsl:when> <xsl:otherwise> <tr class="evenLine"><xsl:copy-of select="$lineHtml" /></tr> </xsl:otherwise> </xsl:choose> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>
大家可能会注意到,上图中的日期和时间列没有解析原始的日期时间字符串。这是因为在我试验时的XSLT 1.0标准中,既没有方便的日期格式化的函数,也不能自定义函数。现在XSLT已经升级的2.0,上述两方面都有改善。但是与用JavaScript相比,使用XSLT来生成HTML受制于XML风格的语法的繁琐,更重要的是没有良好的报错和调试机制,稍有差池,页面只会显示一片空白,很难找到错误根源。
优点:
- 能够完全自定义视图的展示,将其修改成任何所需的外观。
缺点:
- 需要XSLT编程,语法繁琐,难以调试。
- 无法做到像采用JavaScript的方案那样灵活,例如动态地从服务器获取视图的外观数据。
7. XPages中的视图控件
XPages终于将Domino的Web开发带进现代。Web上的视图显示也做到了和客户端一样在设计时所见既所得,视图控件默认生成的显示简洁美观。缘于JSF架构,Domino传送给服务器的是视图控件render生成的HTML,而非前两种方法的XML。视图控件中的分页器(pager)的partialRefresh属性决定翻页时是整页刷新,还是部分刷新(即采用Ajax)。
优点:
- 无需编程。
- 在设计时方便调整外观。
- 一个视图可以用多个视图控件以不同方式展现,节省了后台视图数量,提高了数据库性能。
- 一个页面可以显示多个视图。