论坛首页 Java企业应用论坛

WEB UI定制,XML + XSL解决方案

浏览 2550 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-05-04  
也许你的客户常常有这样的要求,“我的UI要可以定制,我的表单需要有自己的布局格式,而且可以随意添加或去除字段”。那么你要怎样着手去实现呢?
本文以OpenOCE(http://sourceforge.net/projects/openoce/)为案例,向大家讲述在一个企业管理应用系统中UI定制的解决方案。

在开始之前,首先介绍几个概念:
实体(Entity)
略……
字段(Field)
……,每一个字段(类型)都会有一个与之对应的组件,如(Text, Date, FileUpload)
组件(Component)
我们把实体中每一个字段都抽象为一个组件对象,组件可能是一个简单的文本输入框(如用户名),也可能是由几个HTML元素组成在一起的复杂组件(如日期选择框)

下面是来自一个Date组件的所有构成部分
public class Date extends AbstractComponent {	
	private boolean hasTime = false;
	
	public Date(Element col, User user) {
		super(col, user);
	}

	public XSLType getXSLType() {
		return XSLType.Date;
	}

	public void setAttributes() {
		todo...
	}

	@Override
	protected void beforeflush(ComponentAttributes attributes) {
		todo...
	}
}
<col id="birthday" label="user.birthday" type="date" required="true"/>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<xsl:template match="col">
		<td width="130px">  
        todo...   
        </td>
		<td>  
		todo...   
        </td>
	</xsl:template>
</xsl:stylesheet>

Date类会解析XML元素,并针对该组件设置一些的特殊属性,最后通过XSL解析器将该XML转换为HTML,转换后的Date组件如下:
<td width="130px" id="label_birthday">
	<label class="x-form-label-required" for="birthday">Birthday</label>
</td>
<td colspan="1">
<table cellspacing="0" cellpadding="0" border="0" width="100%">
	<tr>
		<td>
			<input maxlength="10" class="x-text" type="text" id="birthday" name="birthday" required="true" system-type="date" value="2008-05-04"/>
		</td>
		<td width="17">
			<div node-type="trigger-date" class="x-trigger x-trigger-date"/>
		</td>
	</tr>
</table>
</td>


下面是一个完整的布局文件
<?xml version="1.0" encoding="UTF-8"?>
<layout entity="Team" action="Entity/Team">
	<section id="baseInfo" label="Form.BaseInfo" display="true">
		<row>
			<col id="teamName" label="team.TeamName" type="text" required="true"/>
		</row>
	</section>
	<section id="privilege" label="Form.Privilege" display="false">
		<row>
			<col id="createdBy" label="CreatedBy" type="search" required="true" />
			<col id="createdOn" label="CreatedOn" type="date" has-time="true" required="true" />
		</row>
		<row>
			<col id="lastModifiedBy" label="LastModifiedBy" type="search" required="true" />
			<col id="lastModifiedOn" label="LastModifiedOn" type="date" has-time="true" required="true" />
		</row>
		<row>
			<col id="owningUser" label="OwningUser" type="search" required="true"/>
			<col id="description" label="Description" type="textarea" />
		</row>
	</section>
</layout>

在上面的布局文件中,我们分为了如下的组成部分:
Layout(Form) 顶级对象,他解析整个布局文件,并将Section元素交由Section对象处理
Section 表单中的一个区域,他包含了若干Row对象,同Form一样,他将若干个Row元素提取,并交由Row对象处理
Row行对象,他包含了1>=N<=2个组件,同样,他也不做最后的解析工作,而是交由Component对象处理
Col(Component) 真正核心的对象,他设置各种属性,默认值及最后的解析工作

最终页面
[img]http://ztojava.iteye.com/upload/picture/pic/13657/63925869-81d7-34a8-a867-37e63f258e7e.gif [/img]


好,现在只要提供一个布局管理器,就能方便的改变布局,设置一些相关属性(如是否必添、是否只读等等),
更美妙的是你还可以在现有字段的基础上进行自定义字段的扩展并应用到布局中,当然这要依赖于你强大的后台支持,毕竟向数据库发送DDL不是闹着玩的,而且很有可能你要抛弃现有的ORM来自己实现一套可动态增减实体字段甚至实体的框架了。
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics