70. 在XPages中展现集合数据

原创 2013年12月05日 17:43:14
 数据绑定机制

本文说的集合简单指多个具有同样结构的数据实体的总和,比如视图的部分或所有文档,查询数据库得到的记录集,一组模型(model)对象等等。在web应用程序里通常用表格来显示这样一个集合。作为基于组件的web框架,XPages提供了几种标准控件来显示这样一个集合:Repeat、View和Data Table。View用于显示一个Notes视图;Data Table以一个表格的形式显示一个集合;Repeat控件最灵活,可以自定义重复的数据显示的形式。深入地看,三者在机制上有很多共同点。它们都是通过value属性绑定到一个数据对象,这个数据对象或是一个DataModel对象,或可以被接合(adapt)成一个DataModel对象。DataModel则是JSF里支持对子组件逐行处理的组件(如UIData)数据绑定的数据源的抽象类【注1】。在JDK里,DataModel有六个直接子类: ArrayDataModel,CollectionDataModel, ListDataModel, ResultDataModel, ResultSetDataModel,ScalarDataModel,也意味着有六类对象可以被接合为一个DataModel:Array、Collection、List、javax.servlet.jsp.jstl.sql.Result、java.sql.ResultSet和一个单独的Java对象。至此我们就清楚地知道XPages自带的Repeat、View和Data Table三种控件可以展示怎样的集合。

我们知道用View控件显示一个Notes视图时,可以用value和data两个属性任意一个来绑定数据源。设置value属性在后台对应com.ibm.xsp.component.xp.XspViewPanel(View控件的Java类)【注2】继承自com.ibm.xsp.component.UIDataEx的setValue(java.lang.Object value)方法,它又是覆盖javax.faces.component.UIData的setValue方法。设置data属性对应com.ibm.xsp.component.xp.XspViewPanel的setData(com.ibm.xsp.model.DataSource data)方法。无论是哪一种,最后都绑定到Notes视图的包装类com.ibm.xsp.model.domino.DominoViewData【注3】

Data Table控件的情况简单些,绑定数据时使用value属性,对应Java类com.ibm.xsp.component.xp.XspDataTableEx同样继承自继承自com.ibm.xsp.component.UIDataEx。

Repeat控件的value属性直接来自Java类com.ibm.xsp.component.UIRepeat的setValue(java.lang.Object value)方法。

各种数据源和一个实例

除了View控件是为Notes视图量身定做的,Data Table和Repeat控件适合展示各种类型的集合数据,在上面提到的六种可接合成DataModel的对象中,javax.servlet.jsp.jstl.sql.Result和java.sql.ResultSet宜用于显示关系型数据库的记录,Array、Collection、List和单独的Java对象则可用于业务逻辑遇到的各种模型数据。下面就用一个实例来演示Repeat控件绑定到一个数组数据源。

样例的派车应用程序介绍:公司在毗邻的几个城市设有办公室,部分员工需要往返各个办公室工作。公司提供若干车辆负责接送员工。需乘车前往异地的员工提前确定行程。公司希望设计一个系统,让员工自行填写乘车申请,负责派车的专员根据申请定时制定出每日的乘车安排,并通知给相关员工。

这个系统的核心是按照员工的乘车申请和可用的汽车和司机资源,自动生成每天的乘车安排表,并可依据临时或特殊情况做手动修改。乘车申请、汽车和司机的资料维护都是一般的新建、修改、查找和删除文档的工作。自动生成的乘车安排表在数据设计上对应一个主文档,表里的每一行(包括司机、汽车、目的地和乘客)可以设计成文档里的一组字段,不过对应一个派车子文档更加灵活和结构清晰。表单、视图和生成主文档子文档的程序不在这里讨论。我们来看看怎样在一个界面上展现乘车安排表。因为涉及到数量不定且可以实时修改的派车文档,如果设计成Notes客户端应用程序,在乘车安排的表单上要么使用隐藏公式来控制一个表格显示和编辑各行派车数据,要么嵌入视图。前者的表格复杂不易维护,而且只适用于以字段组代表派车数据的方案,若选用派车子文档,很难实现界面与数据之间的方便而准确的同步。后者也有多种障碍,首先不方便在主表单的界面里编辑包含派车数据的子文档(Notes视图的InViewEdit功能不好用),需要打开子文档,在另一个窗口编辑;其次主表单和嵌入视图相互隔绝,读取不到对方的信息,以致添加和删除子文档的按钮置于任何一方都难敷应用:放在主表单处,得不到嵌入式图中选中文档的句柄;置于视图上,无法根据主文档的字段设置隐藏公式。设计成web系统,页面可以动态修改,有更大的灵活性。不过如果是传统的Notes web开发,在显示派车数据的表格和承载它们的文档之间双向交流仍然很麻烦。XPages界面与数据分离的策略解决了这个难题。用Repeat控件就可以实现一个绑定到子文档集合的动态的表格。效果如下两图。乘车安排表的主体是一个包含司机、车辆、目的地和乘客四列的表格。在自动生成的安排表上,用户可以修改每一行的内容,也可以新增全新的一行或删除某行。

一张自动生成的乘车安排表


新增一行

这个XPage在设计视图如下:


展示派车数据的表格的代码如下:

<xp:table style="width:90%;margin-left:5%"		rendered="#{javascript:sessionScope.get('showDetails')||!document1.isNewNote();}">
		<xp:tr>
			<xp:td style="width:20%">
				<xp:span style="font-weight:bold">Driver</xp:span>
			</xp:td>
			<xp:td style="font-weight:bold;width:25%">Vehicle</xp:td>
			<xp:td style="font-weight:bold;width:15%">
				Destination/Route
			</xp:td>
			<xp:td style="font-weight:bold">Passengers</xp:td>
		</xp:tr>
		
		<xp:tr>
			<xp:td colspan="4">
				<xp:repeat id="repeat1" rows="30" var="row"
					indexVar="index">
					<xp:this.value><![CDATA[#{javascript:var ids=[];
var dc=document1.getDocument().getResponses();
if (dc===null){
	return ids;
}
var doc=dc.getFirstDocument();
while (doc !== null){
	ids.push(doc.getNoteID());
	doc=dc.getNextDocument(doc);
}
return ids;}]]></xp:this.value>
					<xp:panel>
						<xp:this.data>
							<xp:dominoDocument var="docDetail"
								action="editDocument" formName="Detail"
								documentId="#{javascript:row}" computeWithForm="onsave"
								ignoreRequestParams="true">
							</xp:dominoDocument>
						</xp:this.data>
						<xp:table style="width:100%">
							<xp:tr>
								<xp:td style="width:20%">
									<xp:comboBox id="comboBox1"
										value="#{docDetail.Driver}">
										<xp:selectItem itemLabel="Please select">
										</xp:selectItem><xp:selectItems
											id="selectItems1">
											<xp:this.value><![CDATA[#{javascript:getSetting('Driver');}]]></xp:this.value>
										</xp:selectItems>
										
									</xp:comboBox>
								</xp:td>
								<xp:td style="width:20%">
									<xp:comboBox id="comboBox2"
										value="#{docDetail.Vehicle}">
										<xp:selectItem itemLabel="Please select">
										</xp:selectItem><xp:selectItems
											id="selectItems2">
											<xp:this.value><![CDATA[#{javascript:getSetting('Vehicle');}]]></xp:this.value>
										</xp:selectItems>
										
									</xp:comboBox>
								</xp:td>
								<xp:td style="width:15%">
									<xp:inputText id="inputText1"
										value="#{docDetail.Destination}">
									</xp:inputText>
								</xp:td>
								<xp:td style="width:35%">
									<xp:inputText id="inputText2"
										value="#{docDetail.Passengers}" style="width:95%">
									</xp:inputText>
								</xp:td>
								<xp:td									rendered="#{javascript:document1.isEditable();}">
									<xp:button value="Delete"
										id="button3">
										<xp:eventHandler event="onclick"
											submit="true" refreshMode="complete" id="eventHandler1">
											<xp:this.action><![CDATA[#{javascript:docDetail.getDocument().remove(true);}]]></xp:this.action>
										</xp:eventHandler>
									</xp:button>
								</xp:td>
							</xp:tr>
						</xp:table>
					</xp:panel>
				</xp:repeat>
			</xp:td>
		</xp:tr>
	</xp:table>

外层的表格第一行显示了四个列的标题,第二行唯一的单元格里放置了一个Repeat控件,它的value属性用SSJS计算,为当前文档的子文档的NoteID组成的数组。Repeat控件下只有一个子组件,就是一个Panel,它又包装了代表一行派车数据的一个表格。这样做是因为Panel控件可以包含独立的数据源,在这里即是一个派车子文档,这个xp:dominoDocument由设置documentId为Repeat控件的var属性row获得。这个代表一行派车数据的表格随每一个派车子文档重复一次,它只有简单的一行四列,对应着外层表格的四列。每列依据包容的字段的类型,设有一个组合框或编辑框控件。

再来看看添加一行和删除一行的代码,它们分别位于页面上的Add Vehicle和表格里每一行末尾的Delete按钮里:

<xp:button value="Add Vehicle" id="button4"
			disabled="#{javascript:document1.isNewNote();}">
			<xp:eventHandler event="onclick" submit="true"
				refreshMode="complete">
				<xp:this.action><![CDATA[#{javascript:var doc=database.createDocument();
doc.appendItemValue('Form', 'Detail');
doc.makeResponse(document1.getDocument());
doc.computeWithForm(false, false);	
doc.save();

}]]></xp:this.action>
			</xp:eventHandler>
		</xp:button>
<xp:button value="Delete" id="button3">
	<xp:eventHandler event="onclick" submit="true"  refreshMode="complete" id="eventHandler1">
<xp:this.action><![CDATA[#{javascript:docDetail.getDocument().remove(true);}]]></xp:this.action>
	</xp:eventHandler>
</xp:button>

可以看出,代码很简单,分别只是为当前文档新增了一个子文档和删除一个子文档。其后,从数据到界面的转变就由XPages引擎自动完成。

最后,XPages里的Repeat、View和Data Table这三个控件在JSF的其它实现(implementation)里也有类似的组件。View和Data Table就和Java EE里的javax.faces.component.html.HtmlDataTable都继承自javax.faces.component.UIData,Repeat则在各种facelets技术的版本里都有,如org.apache.myfaces.view.facelets.component.UIRepeat。

 

注1:

原文为DataModel is an abstraction around arbitrary data binding technologies that can be used to adapt a variety of data sources for use by JavaServer Faces components that support per-row processing for their child components (such as UIData).

取自(http://docs.oracle.com/javaee/7/api/javax/faces/model/DataModel.html),可直译为DataModel是JSF里包装任意数据绑定技术的抽象类,这些数据绑定技术可被用于接合不同数据源,这些数据源被用于支持对子组件逐行处理的JavaServer Faces组件(如UIData)。虽然意识更贴近原文,但因为中文表达法的限制,这样的嵌套定语从句读起来有些拗口。

注2:

下面这些Java API可以在XPages Extension API(http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/index.html)查到,XPages控件和模型(model)涉及到的类和接口之繁杂,在笔者看来是缺乏良好架构的明证,不知是因为XPages的设计人员经验不足、分工混乱还是时间仓促。以后还会专文论述。

com.ibm.xsp.component.xp.XspViewPanel

java.lang.Object

 extended by javax.faces.component.UIComponent

     extended by javax.faces.component.UIComponentBase

         extended by javax.faces.component.UIData

              extended by com.ibm.xsp.component.UIDataEx

                  extended bycom.ibm.xsp.component.UIViewPanel

                      extended bycom.ibm.xsp.component.xp.XspViewPanel

 

All Implemented Interfaces:

   FacesAjaxComponent, FacesComponent, FacesDataIterator,FacesNestedDataTable, FacesRefreshableComponent, FacesRowIndex, ThemeControl,javax.faces.component.NamingContainer, javax.faces.component.StateHolder

注3:

com.ibm.xsp.model.domino.DominoViewData

 

java.lang.Object

 extended by com.ibm.xsp.complex.ValueBindingObjectImpl

     extended by com.ibm.xsp.model.AbstractDataSource

         extended by com.ibm.xsp.model.AbstractViewDataSource

              extended bycom.ibm.xsp.model.domino.DominoViewData

 

All Implemented Interfaces:

   ComponentBindingObject, ValueBindingObject, DataPublishingObject, DataSource, ModelDataSource, ViewDataSource, javax.faces.component.StateHolder

xpages repeat在ul在重复显示li

这是第二篇介绍repeat使用的教程,使视图的内容在ul中得以显示,repeat方便,就不用去使用ajax来现实,ajax 实现也行,就是有些代码多 看不懂教程下载demo http://downl...
  • weijia3624
  • weijia3624
  • 2015年03月17日 09:01
  • 718

Victor带你重新认识XPages

本文转自:http://blog.sina.com.cn/s/blog_7010a06601018t1e.html   XPages是Lotus Domino8.5之后加入的全新设计元素,博主曾作...
  • Gavid0124
  • Gavid0124
  • 2015年02月27日 15:00
  • 912

lintcode-二叉树的层次遍历II-70

给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, ...
  • ljlstart
  • ljlstart
  • 2015年09月16日 22:16
  • 1041

JSP 显示集合的方法

最近遇到一个显示集合的问题,在这里记录一下:     List str_list = new ArrayList();     for (int i = 0; i  //对上一个进行封闭,以...
  • qq_21265915
  • qq_21265915
  • 2016年11月23日 09:35
  • 519

Domino/Xpages Bootstrap 动态生成首页功能

由于之前用户需要做个动态首页的功能,但一般用户又不熟HTML,所以最佳的方法可以使用拖动的方法来配置首页,一些基本的组件是已经帮用户的根据实际数据情况已经制作OK,用户只需要简单配置就可以更改首页,还...
  • weijia3624
  • weijia3624
  • 2015年08月18日 10:50
  • 3209

75. XPages中Java开发的一些有用方法

在用Java进行XPages开发时,有一些常见的基础性的任务。这些经常要做的事部分与在Lotus Notes客户端开发时遇到的相同,例如获得当前Session和数据库对象,但是达成的方法与用Lotus...
  • starrow
  • starrow
  • 2013年12月30日 12:29
  • 4114

数据以报表形式展现的实现方法研究

背景:系统的信息业务数据往往我们需要将其显示出来,通常我们用的方式是利用报表的形式将数据打印出来,这样的好处是可以生成形式多样的格式例如pdf,html等等,但是我们也可以使用htp的形式将数据打印出...
  • caixingyun
  • caixingyun
  • 2013年12月14日 11:20
  • 2021

创建并运行第一个 XPages 应用程序

对 IBM Bluemix 上的 Cloud Foundry 应用程序都进行了试用学习,但唯独对 Xpages 应用程序还是一无所知,所以趋周末时间学习了解一下。而要学习使用XPages,貌似就必须使...
  • testcs_dn
  • testcs_dn
  • 2017年04月16日 20:11
  • 968

LeetCode(70) Climbing Stairs

题目You are climbing a stair case. It takes n steps to reach to the top.Each time you can either climb...
  • fly_yr
  • fly_yr
  • 2015年08月19日 21:54
  • 2787

图表:让数据展示一目了然

相信大多数公司的领导都已失去了一字一句看表格和文字的耐心,图表已经成了报表中最常用的数据展现方式之一。这是信息一个过度传播的时代,外界想传递给我们的东西太多,而能有效传达到我们并被我们记住的很少。我们...
  • best_report
  • best_report
  • 2015年03月16日 16:23
  • 1426
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:70. 在XPages中展现集合数据
举报原因:
原因补充:

(最多只允许输入30个字)