在开发项目过程中,我们经常有这样的体会:同一个控件我们可能多处使用,同时我们需要在基础的样式上加上自己的样式和操作的js代码;遇到这种情况,如果每个地方都copy代码的话那么,后期如果要做修改,那么维护的工作量是巨大的,无疑是个灾难。基于这种情况,我们可以考虑使用自定义标签,实现代码的复用,后期的易维护。
先看一张关系图:
上图是我们开发自定义标签常用的接口,我们使用最快捷简便的方式,继承TagSupport类,只需重写doStartTag和doEndtag方法。
一、编写java文件
代码:
public class DataGridColumnTag extends TagSupport{ protected String fields = "";// 显示字段 protected String searchFields = "";// 查询字段 添加对区间查询的支持 private String width; private String height; private boolean checkbox = false;// 是否显示复选框 private boolean showPageList = true;// 定义是否显示页面列表 private boolean openFirstNode = false;// 是不是展开第一个节点 private boolean fit = true;// 是否允许表格自动缩放,以适应父容器 private boolean fitColumns = true;// 当为true时,自动展开/合同列的大小,以适应的宽度,防止横向滚动. private String sortName;// 定义的列进行排序 private String sortOrder = "asc";// 定义列的排序顺序,只能是"递增"或"降序". private boolean showRefresh = true;// 定义是否显示刷新按钮 private boolean showText = true;// 定义是否显示刷新按钮 private String style = "easyui";// 列表样式easyui,datatables private String onLoadSuccess;// 数据加载完成调用方法 private String onClick;// 单击事件调用方法 private String onDblClick;// 双击事件调用方法 private String queryMode = "single";// 查询模式 private String entityName;// 对应的实体对象 private String rowStyler;// rowStyler函数 private boolean autoLoadData = true; // 列表是否自动加载数据 protected static Map<String, String> syscode = new HashMap<String, String>(); static { syscode.put("class", "clazz"); } public void setOnLoadSuccess(String onLoadSuccess) { this.onLoadSuccess = onLoadSuccess; } public void setOnClick(String onClick) { this.onClick = onClick; } public void setOnDblClick(String onDblClick) { this.onDblClick = onDblClick; } public void setShowText(boolean showText) { this.showText = showText; } public void setPagination(boolean pagination) { this.pagination = pagination; } public void setCheckbox(boolean checkbox) { this.checkbox = checkbox; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public void setTreegrid(boolean treegrid) { this.treegrid = treegrid; } public void setWidth(String width) { this.width = width; } public void setHeight(String height) { this.height = height; } //。。。。。。。。。 //其他set方法。。。。 //。。。。。。。。。 public int doStartTag() throws JspTagException { // 清空资源 urlList.clear(); toolBarList.clear(); columnValueList.clear(); columnStyleList.clear(); columnList.clear(); fields = ""; searchFields = ""; return EVAL_PAGE; } public int doEndTag() throws JspException { try { JspWriter out = this.pageContext.getOut(); if (style.equals("easyui")) { out.print(end().toString()); } else { out.print(datatables().toString()); out.flush(); } } catch (IOException e) { e.printStackTrace(); } return EVAL_PAGE; } }
因为继承TagSupport所以重写doStartTag(),doEndTag()。
二、编写.tld文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>t</short-name> <uri>/easyui-tags</uri> <display-name>"自定义标签"</display-name> <tag> <name>datagrid</name> <tag-class>itoo.cgform.base.tag.DataGridTag</tag-class> <body-content>JSP</body-content> <description>数据列表</description> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <description>列表TABLE标示</description> </attribute> <attribute> <name>treegrid</name> <rtexprvalue>true</rtexprvalue> <description>是否是树形列表 值为true 或者false</description> </attribute> <attribute> <name>actionUrl</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <description>分页提交的路径</description> </attribute> <attribute> <name>pagination</name> <rtexprvalue>true</rtexprvalue> <description>是否分页 true,false</description> </attribute> <attribute> <name>title</name> <rtexprvalue>true</rtexprvalue> <description>表格标题</description> </attribute> <attribute> <name>idField</name> <rtexprvalue>true</rtexprvalue> <description>主键字段</description> </attribute> <attribute> <name>width</name> <rtexprvalue>true</rtexprvalue> <description>表格宽度</description> </attribute> <attribute> <name>height</name> <rtexprvalue>true</rtexprvalue> <description>表格高度</description> </attribute> <attribute> <name>checkbox</name> <rtexprvalue>true</rtexprvalue> <description>是否显示复选框</description> </attribute> <attribute> <name>fit</name> <rtexprvalue>true</rtexprvalue> <description>是否适应父容器,true 默认 ,false</description> </attribute> <attribute> <name>sortName</name> <rtexprvalue>true</rtexprvalue> <description>定义的列进行排序</description> </attribute> <attribute> <name>sortOrder</name> <rtexprvalue>true</rtexprvalue> <description>定义列的排序顺序,只能是"递增 asc"或"降序desc"</description> </attribute> <attribute> <name>fitColumns</name> <rtexprvalue>true</rtexprvalue> <description>当为true时,自动展开/合同列的大小,以适应的宽度,防止横向滚动</description> </attribute> <attribute> <name>showPageList</name> <rtexprvalue>true</rtexprvalue> <description>是否显示页面列表</description> </attribute> <attribute> <name>showRefresh</name> <rtexprvalue>true</rtexprvalue> <description>是否显示刷新按钮</description> </attribute> <attribute> <name>showText</name> <rtexprvalue>true</rtexprvalue> <description>是否显示分页信息</description> </attribute> <attribute> <name>style</name> <rtexprvalue>true</rtexprvalue> <description>表格样式easyui,datatables</description> </attribute> <attribute> <name>pageSize</name> <rtexprvalue>true</rtexprvalue> <description>每页显示条数</description> </attribute> <attribute> <name>onLoadSuccess</name> <rtexprvalue>true</rtexprvalue> <description>数据加载成调用方法</description> </attribute> <attribute> <name>onDblClick</name> <rtexprvalue>true</rtexprvalue> <description>双击调用方法</description> </attribute> <attribute> <name>onClick</name> <rtexprvalue>true</rtexprvalue> <description>单击调用方法 tree 下function(rowData),dataGrid 下function(rowIndex,rowData)</description> </attribute> <attribute> <name>queryMode</name> <rtexprvalue>true</rtexprvalue> <description>查询模式:single(单条件查询:默认),group(组合查询)</description> </attribute> <attribute> <name>autoLoadData</name> <rtexprvalue>true</rtexprvalue> <description>列表页面数据加载模式。true自动加载数据,false手动加载,默认为true</description> </attribute> <attribute> <name>openFirstNode</name> <rtexprvalue>true</rtexprvalue> <description>是不是展开第一个节点,在树形情况下,true展开,false不展开默认false</description> </attribute> <attribute> <name>entityName</name> <rtexprvalue>true</rtexprvalue> <description>对应的实体对象,如果entity和controller都是规则的可以不填,自动补全标签做关联</description> </attribute> <attribute> <name>rowStyler</name> <rtexprvalue>true</rtexprvalue> <description>行 css函数 指定名称就可以,调用为 functionName(index,row)这样调用</description> </attribute> <attribute> <name>extendParams</name> <rtexprvalue>true</rtexprvalue> <description>datagrid 的扩展字段,如果easyui上面有但是jeecg没有这个属性可以自己添加 添加规则和easyui的field一致</description> </attribute> </tag> </taglib>
三、调用代码
<t:datagrid sortName="createDate" sortOrder="desc" name="tablePropertyList" title="" fitColumns="false" actionUrl="" idField="id" fit="true" queryMode="group" checkbox="true"> </t:datagrid>
四、界面效果
下面的图描述了容器加载自定义标签的一个过程:首先调用setPageContent方法,jsp引擎会将jsp页转换时隐含创建的pageContext对象作为参数调用setPageContent方法;然后会调用getParent、setParent方法对父标签对象进行设置;之后调用所有的setter方法,将变量全部赋值;上面三步完成后就开始调用doStartTag方法,标志着真正的标签处理开始了;随后调用doEndTag意味着标签处理结束。待所有同类标签处理结束后调用release方法将该标签从内存中清除掉。