在数据保存在关系型数据库的Web开发中。程序猿要处理的是分开的两项任务。一是从数据库中查询记录,二是在视图层生成显示这些数据的HTML。怎样分页是主要问题。Domino以界面为导向的开发风格和不适于动态查询的文档型数据库使得程序猿面临全然不同的处境和问题。预先设计的视图不仅定义了包括的文档,也设置了外观属性,集数据层和外观层的功能于一体。在客户机中,视图拥有和设计时相同的外观,无需编程。
在Web端。由于Domino默认生成的视图HTML过于简陋,程序猿还是须要各种各样的方法改进其外观和操作性。
以下就胪列了我以前接触和使用过的Domino视图Web展现技术,并做了简单分析和评价。
1. 使用Domino生成的HTML
长处:
- 无需编程。
缺点:
- 显示原始简陋。
2. 使用Applet
长处:
- 无需编程。
- 操作与client一致。
缺点:
Applet的全部缺点,包括:
- 用户所在机器需安装Java执行时。尽管眼下大部分机器都已安装。
- 须要下载和加载Applet,速度较慢。
- 与网页总体风格不一致。
- IBM早已放弃其更新。实际上自Java7 Update 51起由于没有提供Java执行时要求的权限属性(Permission Attribute)Domino自带的Applet都无法在浏览器里执行。
3. 将视图内容显示为HTML
这样的方法须要在视图的列公式内计算产生最终的HTML。
长处:
- 能够精细地自己定义显示的内容。
缺点:
- 笨拙繁琐,难以维护。
- 该视图仅仅能用于Web显示,无法通用于client显示和后台查询。
- 列中的大量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命令下Dominoserver发送到浏览器的仅仅有视图的内容数据,不包括字体、颜色等不论什么外观信息。读取它以生成显示视图的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的方案那样灵活,比如动态地从server获取视图的外观数据。
7. XPages中的视图控件
XPages最终将Domino的Web开发带进现代。Web上的视图显示也做到了和client一样在设计时所见既所得,视图控件默认生成的显示简洁美观。缘于JSF架构,Domino传送给server的是视图控件render生成的HTML,而非前两种方法的XML。视图控件中的分页器(pager)的partialRefresh属性决定翻页时是整页刷新,还是部分刷新(即採用Ajax)。
长处:
- 无需编程。
- 在设计时方便调整外观。
- 一个视图能够用多个视图控件以不同方式展现。节省了后台视图数量,提高了数据库性能。
- 一个页面能够显示多个视图。
PS,数年前一同事向我推荐一个OpenNTF上的项目xGrid,用jqGrid来显示视图的XPages自己定义控件。看上去功能繁多。细究却有问题。
jqGrid是一个jQuery插件,在网上应用挺多,甚至还专门出了一本书。可是我看有过度project之嫌,分页、分类、排序、搜索、调整列、导入导出数据、行內编辑……作者想把表格数据显示界面涉及到的全部功能都集中到一个JavaScript插件里。用力过猛。分页、排序、搜索这些功能都应由server端处理数据,前端脚本仅仅能发挥触发和显示的作用,即使前端插件的功能无所不包,没有server端可调用的接口也仅仅是摆设,而server端这些操作数据的逻辑依赖于编程语言、数据库、数据设计和业务需求各有不同,让它们都来适应一个前端插件的接口。有些本末倒置,削足适履。jqGrid插件为了涵盖繁多功能和各种server端技术。实现最大程度的灵活。必需大量的配置,要学习这样一个万能而臃肿的插件怎样使用,也不是一件小事了。
以上还仅仅是jqGrid插件的问题,xGrid的缺陷更是致命的。jqGrid对表格里显示的数据,一般是须要时(如翻页)才从server读取。搜索也是将请求发送到server,可是它也能够一次加载全部数据,以后全部的功能都由JavaScript操作这些本地数据。这当然是被设计成展现少量静态数据时的使用方法,可是xGrid居然仅仅能一次性读取全部数据(loadOnce属性仅仅能设置true),除非是文档数量非常少的配置视图,对不论什么正常大小的视图,一打开就下载全部数据既是对server和带宽的考验,也是毫无必要的浪费。后来的分类、排序、搜索种种操作,尽管看上去华丽。但在数据量大的情况下。性能必定低下——JavaScript本就不是设计用来在浏览器内处理大量数据的。
更滑稽的是,当时我在一个中文Lotus技术论坛里看到讨论这个插件的文章。挑战速度极限一次性下载五万条文档的数据。
我不禁想,这是在探索Domino视图展示的新技术。还是在做让Dominoserver宕机的极限測验。就算server没被折磨死。视图打开后,随便转到另外一个页面这五万条文档的数据就白下载了,再打开那个视图,又要折磨server和网络一遍。
提上面这个插曲,是想说明。视图的展示要兼顾前端的美观和后台的性能,还要考虑程序猿实现和维护起来方便,突出一点而偏废其它都不是好的架构。