在开发项目过程中,我们经常有这样的体会:同一个控件我们可能多处使用,同时我们需要在基础的样式上加上自己的样式和操作的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方法将该标签从内存中清除掉。