1. 功能介绍

    页面生成,将复杂的页面中的内容元素拆分形成多个页面组件,页面内容元素通过配置文件组装形成,在简化页面代码的同时并提供对页面内容元素的灵活定制化。

  2. 主要特性

    1. 页面配置文件的向导式可视化配置,开发者可以根据自定义文件、LCU流程文件、表结构、SQL语句查询出的字段或数据生成组件参数及配置文件。
    2. 通过生成的配置文件可以通过页面生成组件直接生成页面。
    3. 配置文件里的页面元素及页面组件,写法兼容HTML写法,保证组件的兼容性,避免重复开发,即:HTML组件代码与页面配置文件里的组件可以互相拷贝、互相兼容。
    4. 页面生成不做全页面生成,只关注主体内容元素,保证主体页面的动态性的同时,也保证页面的开发模式的一致性。
    5. 页面生成除了控制主体元素的排放布局外,外围布局由HTML提供,HTML布局嵌入页面生成组件,最大方式灵活开发.
    6. 提供配置文件或页面生成配置数据生成页面,减少业务数据与业务表结构对业务生成配置的依赖性,这样不论用什么样的表结构,只要形成规格的配置对象,都能保证页面生成的一致性。
  3. 开发步骤

    1. 生成配置文件。通过图形化配置工具配置页面布局并生成配置文件,也可以手工编写页面布局配置文件。图形化工具提供了:从文件系统生成配置文件;通过LCU生成的XML文件生成配置文件;通过数据表结构生成配置文件;通过手工编写SQL,按SQL查询字段或SQL查询数据生成配置文件。配置过程中提供页面布局预览功能。
    2. 在HTML中编写页面生成组件[行列式布局:BuilderRow;表格式布局:BuilderTable]。
  4. 配置文件说明

    1. page: 页面配置

      name 配置页面名称
      scout true|false,是否缓存页面配置文件默认缓存
    2. layout: 布局配置

      name 布局名称
      aclinic On|Off,控制输入组件与描述信息的排列方式,On:纵向排列,Off:横向排列,仅用行列式布局(BuilderRow)时有效
      columns 非零正整数值,控制每行排列的组件列数,仅用行列式布局(BuilderRow)时有效
      [其它] 可扩展任意的XHTML元素属性(如class,style...)和任意HTML事件属性(onclick,onmouseover,onmouseout...)
    3. component: 组件配置

      与WADE组件定义及写法一致,需要注意XML格式的特殊字符需要转换,XML特殊字符参看下面表格说明:

      符号名 样式 代码
      小于号 < &lt;
      大于号 > &gt;
      和与号 & &amp;
  5. 方法说明

    类路径 com.linkage.webframework.pagebuilder.BuilderFactory
    类描述 页面生成工厂类
    方法名称 public static IData builderData(String file) throws Exception
    方法描述 根据配置文件生成配置数据,文件必需是完整路径
    方法名称 public static boolean builderXml(IData data) throws Exception
    方法描述 根据配置数据生成配置文件,配置数据必需符合配置要求
    方法名称 public static boolean builderXml(String file, IData data, String layoutname, boolean rescissory) throws Exception
    方法描述 根据配置数据生成配置文件,文件必需是完整路径,配置数据必需符合配置要求,如果file为null或"",则不生成文件;如果layoutname为null或为"", 生成所有layout,如果rescissory为true则保存至文件
  6. 注意事项

    1. 配置文件存放在etc/省代码../pagexml/目录下,如pagexml/example/vipcust.xml,在HTML编写组件时需要引入pagexml并去掉文件名后缀".xml",如:pagexml.example.vipcust。
    2. 当只需要一个配置文件里的某几个布局时,写法如下layouts="pagexml.example.vipcust@vipcustquery,pagexml.example.vipcust@vipcustedit"
    3. 预览配置需加上preview="true"
  7. 代码片段

    1. HTML页面代码

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head jwcid="@wade:Head">
      <meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
      <title>Vipcust List</title>
      <link jwcid="@wade:Style" href="component/ecl/skin/defaultSkin/defaultColor/color.css" rel="stylesheet" type="text/css" media="screen"/>
      </head>
      <body jwcid="@Body">
      <!-- 外框必须在form之外,如果不需要边距,比如嵌套的子页面,div class="e_wrapper2"需要去掉 -->
      <div class="e_wrapper"><div class="e_wrapper2">
      <form jwcid="@Form">
      	<!-- 提示信息组件,在hint.txt中定义,也可以通过页面类的setHintInfo,setAlertInfo,setErrorInfo来设置该信息 -->
      	<div jwcid="@wade:HintBar" hintInfo="ognl:hintInfo" alertInfo="ognl:alertInfo" errorInfo="ognl:errorInfo"/>
      	
      	<!-- 编辑区,l_mt表示与上之间有一个间距,间距需要视页面布局来定义 -->
      	<div class="c_inputField l_mt">
      		<div class="top"></div>
      		<!--查询条件输入区,采用行列式布局组件BuilderRow,layouts所指定的是classes目录下的pagexml/vipcust.xml文件,布局名称为vipcustquery -->
      		<div jwcid="@wade:BuilderRow" layouts="pagexml.vipcust@vipcustquery"/>
      		<div class="bottom e_rSet">
      			<!-- 查询按钮必须触发queryXXX方法 -->
      			<input type="submit" jwcid="bquery@Submit" value="执行查询" listener="ognl:listeners.queryVipcusts" class="e_button" onclick="return queryAll(this)"/>
      			<input type="submit" jwcid="bcall@Submit" value="CallTuxedo" listener="ognl:listeners.callTuxTest" class="e_button" onclick="return queryAll(this)"/>
      		</div>
      	</div>
      	
      	<!-- 刷新区域,用于ajax刷新,如分页时刷新表格 -->
      	<div id="VipcustPart" jwcid="@wade:Part" optimize="true">
      	<div class="c_table l_mt"><div class="nowrapOn">
      		<div class="fctTop e_clear">
      			<div class="fctLeft">
      				<div class="button">
      					<ul>
      						<li><a jwcid="@wade:PageRedirect" value="反选" class="e_bLinkSelect" onclick="checkedOther('vips')"/></li>
      						<!-- 删除等操作不要再用LinkSubmit组件,通过pageSubmit(this, 'deleteVipcusts')方法替代 -->
      						<li><a jwcid="@wade:PageRedirect" value="删除" desc="VIP客户资料" class="e_bLinkDelete" onclick="if (!queryBox(this, 'vips')) return false;pageSubmit(this, 'deleteVipcusts')"/></li>
      						<!-- 导入用弹出窗口,如果在需要传递查询条件到导入页面,需要加上source="ognl:condition",这样从导入完成后返回到主页面时能够将条件传回 -->
      						<li><a jwcid="@wade:PageRedirect" value="导入" class="e_bLinkUp" onclick="return popupDialog('examples.basic.VipcustImport', null, parameters, 'VIP客户资料批量导入', '400', '300')"/></li>
      						<!-- 导出需要将condition条件传入,否则导出的数据将没有提交过滤,若需要控制权限,需要在@wade:Head中设置priv,exportFile加上最有一个权限编码的参数 -->
      						<li><a jwcid="@wade:PageRedirect" value="导出" source="ognl:condition" desc="VIP客户资料" class="e_bLinkDown" onclick="return exportFile('examples.basic.VipcustList', 'exportVipcusts', parameters)"/></li>
      						<li><a jwcid="@wade:PageRedirect" source="ognl:condition" value="新增" caption="新增VIP客户资料" class="e_bLinkAdd" onclick="redirectTo('examples.basic.VipcustEdit', null, parameters)"/></li>
      					</ul>
      				</div>
      			</div>
      			<div class="fctRight">
      				<!-- 分页,由于带有checkbox,可以设置checkbox参数,这样翻页后能够记住前些页的勾选值 -->
      				<div jwcid="@wade:NavBar" source="ognl:infos" listener="ognl:listeners.queryVipcusts" refreshParts="VipcustPart" checkboxName="vips"/>
      			</div>
      		</div>
      		<!-- 查询结果列表区,采用列表式布局组件BuilderTable,layouts所指定的是classes目录下的pagexml/vipcust.xml文件,布局名称为vipcustlist  -->
      		<div jwcid="@wade:BuilderTable" layouts="pagexml.vipcust@vipcustlist" source="ognl:infos" value="ognl:info" />
      		<div class="fctBottom e_clear">
      			<div class="fctLeft">
      				<div class="button">
      					<ul>
      						<li><a jwcid="@wade:PageRedirect" value="反选" class="e_bLinkSelect" onclick="checkedOther('vips')"/></li>
      						<!-- 删除等操作不要再用LinkSubmit组件,通过pageSubmit(this, 'deleteVipcusts')方法替代 -->
      						<li><a jwcid="@wade:PageRedirect" value="删除" desc="VIP客户资料" class="e_bLinkDelete" onclick="if (!queryBox(this, 'vips')) return false;pageSubmit(this, 'deleteVipcusts')"/></li>
      						<!-- 导入用弹出窗口,如果在需要传递查询条件到导入页面,需要加上source="ognl:condition",这样从导入完成后返回到主页面时能够将条件传回 -->
      						<li><a jwcid="@wade:PageRedirect" value="导入" class="e_bLinkUp" onclick="return popupDialog('examples.basic.VipcustImport', null, parameters, 'VIP客户资料批量导入', '400', '300')"/></li>
      						<!-- 导出需要将condition条件传入,否则导出的数据将没有提交过滤,若需要控制权限,需要在@wade:Head中设置priv,exportFile加上最有一个权限编码的参数 -->
      						<li><a jwcid="@wade:PageRedirect" value="导出" source="ognl:condition" desc="VIP客户资料" class="e_bLinkDown" onclick="return exportFile('examples.basic.VipcustList', 'exportVipcusts', parameters)"/></li>
      						<li><a jwcid="@wade:PageRedirect" source="ognl:condition" value="新增" caption="新增VIP客户资料" class="e_bLinkAdd" onclick="redirectTo('examples.basic.VipcustEdit', null, parameters)"/></li>
      					</ul>
      				</div>
      			</div>
      			<div class="fctRight">
      				<!-- 分页,由于带有checkbox,可以设置checkbox参数,这样翻页后能够记住前些页的勾选值 -->
      				<div jwcid="@wade:NavBar" source="ognl:infos" listener="ognl:listeners.queryVipcusts" refreshParts="VipcustPart" checkboxName="vips"/>
      			</div>
      		</div>
      	</div></div>
      	</div>
      </form>	
      </div></div>
      </body>
      </html>
      
    2. 配置文件代码

      <?xml version="1.0" encoding="GB2312"?>
      <page LAYOUT_TYPE="1" name="vipcust" scout="true">
      	<layout aclinic="On" columns="3" name="vipcustquery">
      		<input class="e_input" datatype="text" desc="开始时间" jwcid="cond_START_DATE@wade:DateField" nullable="yes" value="ognl:condition.cond_START_DATE" />
      		<input class="e_input" datatype="text" desc="结束时间" jwcid="cond_END_DATE@wade:DateField" nullable="yes" value="ognl:condition.cond_END_DATE" />
      		<input class="e_input" blank="true" datatype="text" desc="客户经理" jwcid="cond_CUST_MANAGER_ID@component:ManagerField" nullable="yes" value="ognl:condition.cond_CUST_MANAGER_ID" />
      		<input class="e_select" datatype="text" desc="VIP类型" jwcid="cond_VIP_TYPE_CODE@PropertySelection" model="ognl:@com.linkage.component.util.Utility@getStaticSelection(page, '#td_m_viptype')" nullable="yes" value="ognl:condition.cond_VIP_TYPE_CODE" />
      		<input class="e_select" datatype="text" desc="VIP级别" jwcid="cond_VIP_CLASS_ID@PropertySelection" model="ognl:@com.linkage.component.util.Utility@getStaticSelection(page, '#td_m_vipclass')" nullable="yes" value="ognl:condition.cond_VIP_CLASS_ID" />
      		<input class="e_input" datatype="text" desc="VIP标识" jwcid="cond_VIP_ID@wade:TextField" nullable="yes" value="ognl:condition.cond_VIP_ID" />
      		<input class="e_input" datatype="text" desc="客户名称" jwcid="cond_USECUST_NAME@wade:TextField" nullable="yes" value="ognl:condition.cond_USECUST_NAME" />
      		<input class="e_input" datatype="text" desc="证件号码" jwcid="cond_USEPSPT_ID@wade:TextField" nullable="yes" value="ognl:condition.cond_USEPSPT_ID" />
      		<input class="e_input" datatype="text" desc="服务号码" jwcid="cond_SERIAL_NUMBER@wade:TextField" nullable="yes" value="ognl:condition.cond_SERIAL_NUMBER" />
      	</layout>
      	<layout aclinic="On" columns="3" name="vipcustlist">
      		<input datatype="text" desc="vips" jwcid="vips@wade:Checkbox" nullable="no" onclick="checkedAll('vips', checked)" value="ognl:info.VIP_ID" />
      		<input columns="VIP_ID" datatype="text" desc="VIP标识" jwcid="VIP_ID@wade:PageRedirect" nullable="no" onclick="redirectTo('examples.basic.BuilderVipcustEdit', 'queryVipcust', parameters)" source="ognl:info" title="ognl:info.VIP_ID" value="ognl:info.VIP_ID" />
      		<input datatype="text" desc="客户名称" jwcid="USECUST_NAME@Insert" nullable="no" raw="true" value="ognl:info.USECUST_NAME" />
      		<input datatype="text" desc="服务号码" jwcid="SERIAL_NUMBER@Insert" nullable="no" raw="true" value="ognl:info.SERIAL_NUMBER" />
      		<input datatype="text" desc="证件号码" jwcid="USEPSPT_ID@Insert" nullable="yes" raw="true" value="ognl:info.USEPSPT_ID" />
      		<input datatype="text" desc="VIP类型" jwcid="VIP_TYPE_CODE@Insert" nullable="no" raw="true" value="ognl:@com.linkage.component.util.Utility@getStaticValue(page, '#td_m_viptype', info.VIP_TYPE_CODE)" />
      		<input datatype="text" desc="VIP等级" jwcid="VIP_CLASS_ID@Insert" nullable="no" raw="true" value="ognl:@com.linkage.component.util.Utility@getStaticValue(page, '#td_m_vipclass', info.VIP_CLASS_ID)" />
      		<input datatype="text" desc="客户经理" jwcid="CUST_MANAGER_ID@Insert" nullable="yes" raw="true" value="ognl:@com.linkage.component.util.Utility@getStaticValue(page, 'TD_M_STAFF', 'STAFF_ID', 'STAFF_NAME', info.CUST_MANAGER_ID)" />
      		<input datatype="text" desc="加入时间" jwcid="JOIN_DATE@Insert" nullable="no" raw="true" value="ognl:@com.linkage.component.util.Utility@decodeTimestamp('yyyy-MM-dd HH:mm', info.JOIN_DATE)" />
      	</layout>
      </page>
      
  8. 注意事项

    1. 配置文件存放在etc/省代码../pagexml/目录下,如pagexml/example/vipcust.xml,在HTML编写组件时需要引入pagexml并去掉文件名后缀".xml",如:pagexml.example.vipcust。
    2. 当只需要一个配置文件里的某几个布局时,写法如下:
      layouts="pagexml.example.vipcust@vipcustquery,pagexml.example.vipcust@vipcustedit"
    3. 预览配置需加上preview="true"
  9. 效果演示

    页面生成配置

    页面生成预览

    页面生成源码分析

    页面生成效果