一、问题概述 |
在开发web信息管理系统时,使用Web前端框架可以帮助我们快速搭建一组风格统一的界面效果,而且能够解决大多数浏览器兼容问题,提升开发效率。在关于LigerGrid的前两篇的内容里,给大家介绍了表格的基本的展示数据用法。(传送门:LigerUI之Grid使用详解(一)——显示数据 、LigerUi之Grid使用详解(二)——数据编辑 )
在实际应用开发中,我们会经常遇到这样的场景,在展示业务数据的时候需要把业务数据中的参数项或者字典项的编码转换成参数名称或者字典名称展示出来。在这里本人总结了三种解决方案,并做了对比。
二、表格中显示字典数据 |
首先创建字典表和业务数据表,创建字典参数表,并插入数据:
CREATE TABLE SYSPARAMS ( PID VARCHAR2(10), CATEGORYCODE VARCHAR2(10), CATEGORYNAME VARCHAR2(50), PCODE VARCHAR2(10), PNAME VARCHAR2(50), ENABLED CHAR(1) DEFAULT 1, SORTNO NUMBER, REMARK VARCHAR2(100) ); ALTER TABLE SYSPARAMS ADD CONSTRAINT SYSPARAMS_PK_PID PRIMARY KEY (PID); INSERT INTO SYSPARAMS VALUES(‘1000000001‘,‘PARTSBRAND‘,‘配件品牌‘,‘1‘,‘三一‘,‘1‘,1,‘‘); INSERT INTO SYSPARAMS VALUES(‘1000000002‘,‘PARTSBRAND‘,‘配件品牌‘,‘2‘,‘徐工‘,‘1‘,2,‘‘); INSERT INTO SYSPARAMS VALUES(‘1000000003‘,‘PARTSBRAND‘,‘配件品牌‘,‘3‘,‘中联‘,‘1‘,3,‘‘);
创建业务表,并插入测试数据:
CREATE TABLE BIZ_PARTS ( PCODE VARCHAR2(10), PNAME VARCHAR2(50), PBRAND VARCHAR2(10), PNO VARCHAR2(50), PGENNO VARCHAR2(50), PMODEL VARCHAR2(50), PSIZE VARCHAR2(20), PWEIGHT VARCHAR2(10), PUNIT VARCHAR2(10), PSPRICE NUMBER(10,2), REMARK VARCHAR2(100) ); ALTER TABLE BIZ_PARTS ADD CONSTRAINT BIZ_PRATS_PK_PCODE PRIMARY KEY (PCODE); INSERT INTO BIZ_PARTS VALUES(‘PJ00000001‘,‘DH150主控阀‘,‘1‘,‘DB11-1-50/315‘,‘‘,‘DB11-1-50/315‘,NULL,NULL,NULL,200,NULL); INSERT INTO BIZ_PARTS VALUES(‘PJ00000002‘,‘EC360液压泵‘,‘2‘,‘DB10-2-30/315‘,‘‘,‘DB10-2-30/33333‘,NULL,NULL,NULL,300,NULL); INSERT INTO BIZ_PARTS VALUES(‘PJ00000003‘,‘DH420斗齿‘,‘3‘,‘DB20-1-30/315‘,‘‘,‘DB20-1-30/315555‘,NULL,NULL,NULL,300,NULL);
数据准备好之后,我们分别来看看这三种解决方案是如何实现的。
解决方案一
首先来看第一种解决方案,在这种解决方案中,前台需要显示什么数据,我们在后台就查询什么数据传递给前台,即在后台查询时,采用表连接查询或者子查询的方式将数据查询出,并封装成实体集合传递给前台。查询SQL如下:
SELECT B.PCODE, B.PNAME, B.PBRAND, P.PNAME AS PBRANDNAME, B.PNO, B.PMODEL, B.PSPRICE FROM BIZ_PARTS B, SYSPARAMS P WHERE B.PBRAND = P.PCODE AND P.CATEGORYCODE = ‘PARTSBRAND‘;
或者:
SELECT B.PCODE, B.PNAME, B.PBRAND, B.PNO, B.PMODEL, B.PSPRICE, (SELECT P.PNAME FROM SYSPARAMS P WHERE B.PBRAND = P.PCODE AND P.CATEGORYCODE = ‘PARTSBRAND‘) AS PBRANDNAME FROM BIZ_PARTS B;
最终结果呈现如下:
此解决方案优点是前台无需做任何处理即可展示我们想看到的数据,缺点是增加查询复杂度,增加实体属性,并且业务数据和参数数据在混杂在一起,不利于后期维护和扩展。
解决方案二
直接查询业务数据,所有展示问题交给前台处理,步骤如下:
1、 编写查询SQL:
SELECT B.PCODE, B.PNAME, B.PBRAND, B.PNO, B.PMODEL, B.PSPRICE FROM BIZ_PARTS B;
2、 将查询数据展示在前台表格中。
$("#maingrid").ligerGrid({ columns:[ {display:"配件名称",name:"name",isAllowHide:false,align:"left",width:140}, {display:"配件品牌",name:"brandCode",isAllowHide:false,align:"left",width:120}, {display:"配件件号",name:"no",isAllowHide:false,align:"left",width:120}, {display:"配件型号",name:"model",isAllowHide:false,align:"left",width:140}, {display:"单价",name:"price",type:"float",isAllowHide:false, align:"left",width:80, render:function(item){ return formatCurrency(item.price); } } ], rownumbers:true, isScroll:true, url:"main/bizParts.action?reqCode=findOnlyBizParts", width:"99.7%" });
效果如下:
可以看到配件品牌展示的是编码,我们需要将其转换为名称字符,继续改造代码。
3、 使用ajax将本业务数据中用到的字典数据加载到本页面后,再去构建表格,并利用表格的render属性对单元格内容进行渲染。
A、使用ajax将配件品牌字典查询保证到页面,代码如下:
$.post("main/bizParts.action?reqCode=findSysParamsByCategoryCode", {code:"PARTSBRAND"}, function(data){ brandData = data; init_grid(); },"json");
B、参数数据加载成功后,初始化表格并在表格的配件品牌列中添加渲染函数
{display:"配件品牌",name:"brandCode",isAllowHide:false,align:"left",width:120, render:function(item){ for(var i=0;i<brandData.length;i++){ if(item.brandCode==brandData[i].pcode){ return brandData[i].pname; } } } }
最终效果如方案一。此解决方案优点在于后台数据解耦,有利于后期的维护和扩展,缺点在于除了专注于业务数据的同时,还要处理相关参数数据。
解决方案三
采用自定义标签,将字典数据的获取及渲染函数全部封装到自定义标签中,这样我们在用到字典的时候直接使用标签即可。具体步骤如下:
1、 编写标签处理类:在此做简单处理,渲染函数的命名方式为:render_字典类型编号。实际上字符连接这块内容,我们应该定义成tpl模板。
public class JreduSysParamsTag extends SimpleTagSupport { private String categoryCode; public String getCategoryCode() { return categoryCode; } public void setCategoryCode(String categoryCode) { this.categoryCode = categoryCode; } @Override public void doTag() throws JspException, IOException { SysParamsService sysParamService = new SysParamsServiceImpl(); List<Map<String, String>> list =sysParamService.findSysParamsByCategoryCode(categoryCode); JSONArray array = JSONArray.fromObject(list); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("<script>"); stringBuilder.append(" var data_").append(categoryCode).append("="); stringBuilder.append(array.toString()); stringBuilder.append(";"); stringBuilder.append("function "); stringBuilder.append("render_").append(categoryCode); stringBuilder.append("(item,item1,item2,cell){"); stringBuilder.append("for( var i=0;i<data_").append(categoryCode).append(".length;i++){"); stringBuilder.append("if(item[cell.name]==data_").append(categoryCode).append("[i].id){"); stringBuilder.append("return data_").append(categoryCode).append("[i].text;"); stringBuilder.append("}"); stringBuilder.append("}"); stringBuilder.append("}"); stringBuilder.append("</script>"); getJspContext().getOut().write(stringBuilder.toString()); } }
2、 编写标签库文件:
<tag> <name>JreduSysParams</name> <tagclass>com.jereh.edu.tag.JreduSysParamsTag</tagclass> <bodycontent>empty</bodycontent> <attribute> <name>categoryCode</name> <required>true</required> </attribute> </tag>
3、 在jsp页面中结合ligerGrid使用此标签。
<jredu:JreduSysParams categoryCode="PARTSBRAND"/>
修改grid列的render:
{display:"配件品牌",name:"brandCode",isAllowHide:false,align:"left",width:120, render:render_PARTSBRAND }
最终效果如下:
综上所述,方案三不仅解决了之前两种方案中的问题,还能够实现组件的重用,在此推荐大家使用此方案解决表格中显示字典数据的问题。
※ 源码下载
如需源码,请点击百度云源码下载:http://pan.baidu.com/s/1gd6DIYv ,欢迎分享。