摘要:一、服务器端的实现  由于之前已经有过实现的经验,因此服务器端的实现已经轻车熟路,下边先介绍这一块。

小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

一、服务器端的实现

  由于之前已经有过实现的经验,因此服务器端的实现已经轻车熟路,下边先介绍这一块。

  其实从面向对象的角度来说,特别是采用了SSH框架之后,我们可以直接通过hibernate获取对应表对象的集合,然后将集合发送至前台交给Ext处理。这样看起来挺不错,而且实际实现也不难,但是你仔细查看就会发现个很不爽的事情,每次发送的集合包含了大量的无用数据(甚至绝大多数的数据),为什么会这样呢?表关联的原因。hibernate生成的model会引入关联表的对象(或对象集合),而struts—json插件会将他们全部序列化,这在我们实际Ext的显示中不需要的。当然,你或许可以无视,但这绝对是个糟糕的设计,你将大量的网络流量耗费在了无效数据上。

  那么怎么解决这个问题呢?有两个方法:一是通过struts—json提供的方法(一般用注解或result配置)指定这些数据不序列化,听着挺好,但做着费劲,你要么在model类中写入很多和这个类本身没有任何关系的注解,要么需要就在action的标签内对每一个字段进行指定,这个听听都头疼;另外一种方法或许靠谱些,可以对每个model对应一个简化的model,在hibernate读取集合后将集合转化为该类型的,事实上我在处理多表关联数据显示时就用的这个方法,但是你觉得对于每个实体定义两个model合适吗?

  既然这两种都不行,那么怎么处理呢?其实完全可以抛开hibernate,采用原始点的方法:先sql读取所有表名,然后根据表名读出字段名和对应数据,其中表数据使用二维数据存数即可,事实证明这种方法更灵活。

  下边是实现代码:

View Code
? 1???? /**
? 2????? * 获取表名
? 3????? * @return??? List<表明>
? 4????? */
? 5???? public List getTables(){
? 6???????? List mdbls=new ArrayList();
? 7???????? Session se=HibernateSessionFactory.getSession();
? 8???????? SQLQuery sq=se.createSQLQuery("show tables");
? 9???????? List sls=sq.list();
?10???????? for(String str:sls){
?11???????????? if("jbpm".equals(str.substring(0, 4)))
?12???????????????? continue;
?13???????????? MyDataBase mdb=new MyDataBase();
?14???????????? mdb.setTablename(str);
?15???????????? mdbls.add(mdb);
?16???????? }
?17???????? return mdbls;
?18???? }
?19????
?20???? /**
?21????? * 获取字段名???
?22????? * @param tablename??? 表名
?23????? * @return
?24????? */
?25???? public List getFields(String tablename){
?26???????? List mdbls=new ArrayList();
?27???????? Session se=HibernateSessionFactory.getSession();
?28???????? SQLQuery sq=se.createSQLQuery("desc "+tablename).addScalar("Field");
?29???????? List sls=sq.list();
?30???????? for(String str:sls){
?31???????????? MyDataBase mdb=new MyDataBase();
?32???????????? mdb.setFieldname(str);
?33???????????? mdbls.add(mdb);
?34???????? }
?35???????? return mdbls;
?36???? }
?37????
?38???? /**
?39????? * 获取字段
?40????? * @param tablename 表名
?41????? * @return
?42????? */
?43???? public String[] getFieldsInArray(String tablename){
?44???????? String[] fields;
?45???????? Session se=HibernateSessionFactory.getSession();
?46???????? SQLQuery sq=se.createSQLQuery("desc "+tablename).addScalar("Field");
?47???????? List sls=sq.list();
?48???????? fields=new String[sls.size()];
?49???????? for(int i=0;i<>
?50???????????? fields[i]=sls.get(i);
?51???????? }
?52???????? return fields;
?53???? }
?54????
?55???? /**
?56????? * 获取表内容
?57????? * @param tablename
?58????? * @return
?59????? */
?60???? public String[][] getTableContent(String tablename){
?61???????? String[][] content=null;
?62???????? Session se=HibernateSessionFactory.getSession();
?63???????? SQLQuery sq=se.createSQLQuery("select * from "+tablename);
?64???????? List ls=sq.list();
?65???????? content=new String[ls.size()][getFields(tablename).size()];
?66???????? for(int i=0;i<>
?67???????????? Object[] strs=ls.get(i);
?68???????????? for(int j=0;j<>
?69???????????????? content[i][j]=strs[j]==null?"":strs[j].toString();
?70???????????? }
?71???????? }
?72???????? return content;
?73???? }
?74????
?75???? /**
?76????? * 将字段名集合处理为JSON格式的字符串
?77????? * @param tablename??? 对应表名
?78????? * @return??? 字符串数组,每一项为一个Ext中grid的一个header
?79????? */
?80???? public String[] getfiledsHeaders(String tablename){
?81???????? String[] fields=this.getFieldsInArray(tablename);
?82???????? String[] content=new String[fields.length];
?83???????? String temp="{text:'#1',dataIndex:'#1',flex:1}";
?84????????
?85???????? for(int i=0;i<>
?86???????????? content[i]=temp.replace("#1", fields[i]);
?87???????? }
?88???????? return content;
?89???? }
?90????
?91???? /**
?92????? * 将数据处理为JSON格式的字符串
?93????? * @param tablename??? 对应表名
?94????? * @return??? 字符串数组,每一项为一条数据库记录
?95????? */
?96???? public String[] getContentStr(String tablename){
?97???????? String[] fields=this.getFieldsInArray(tablename);
?98???????? String[][] content=this.getTableContent(tablename);
?99???????? String jsonContent[]=new String[content.length];
100???????? for(int i=0;i<>
101???????????? String temp="";
102???????????? for(int j=0;j<>
103???????????????? temp=temp+"'"+fields[j]+"':'"+content[i][j]+"',";
104???????????? }
105???????????? temp="{"+temp.substring(0, temp.length()-1)+"}";
106???????????? jsonContent[i]=temp;
107???????? }
108????
109???????? return jsonContent;
110???? }  其中最终发送客户端的字段头格式如下:

"fieldheader":["{text:'rid',dataIndex:'rid',flex:1}","{text:'rname',dataIndex:'rname',flex:1}","{text:'rstring',dataIndex:'rstring',flex:1}"],"fields":["rid","rname","rstring"]  表数据格式如下:

"contentstr":["{'rid':'1','rname':'系统管理员','rstring':'admin'}","{'rid':'2','rname':'实训负责人','rstring':'manager'}","{'rid':'3','rname':'指导老师','rstring':'teacher'}","{'rid':'4','rname':'组长','rstring':'header'}","{'rid':'5','rname':'学生','rstring':'student'}"]二、Extjs中grid的实现

  其实实现动态grid的思路很简单,我们知道grid的表头是由columns属性指定的,而加载的数据是由对应的store决定的,想要让其动态改变,只需修改columns和store即可,而恰好Ext提供了reconfigure(Ext.data.Store store, Object[] columns)方法来实现这一操作。

  Extjs里边首先需要一个combox下拉框,在打开grid的时候加载表名以供选择,其实现如下:

{
???????????????? xtype: 'combobox',
???????????????? width: 219,
???????????????? id:'combtables',
???????????????? fieldLabel: '选择表',
???????????????? labelWidth: 50,
???????????????? maxWidth: 200,
???????????????? editable:false,
???????????????? valueField: 'tablename',
???????????????? displayField: 'tablename',
???????????????? store:Ext.create('sxpt.store.admin.Tables'),      //对应store请求获取表名
???????????????? labelWidth: 80
}  为实现动态的grid,我们首先要实现一个未指定store和空columns的grid,其实现代码如下:

View Code
?1 Ext.define('sxpt.view.admin.DataBaseList',{
?2???? extend: 'Ext.grid.Panel',
?3???? alias: 'widget.databaselist',
?4???? id:'databaselist',
?5???? title: '数据库管理',?
?6???? region: 'center',
?7???? renderTo:Ext.getBody(),
?8???? columns:[],
?9???? bbar: {?
10???????? xtype: 'pagingtoolbar',
11???????? id:'datapagebar',
12???????? displayInfo: true,
13???????? displayMsg: '显示 {0} - {1} 共 {2}条',?
14???????? emptyMsg: "没有数据需要显示"?
15???? },
16?????? dockedItems:[{
17?????????? dock: 'top',
18?????????? xtype: 'toolbar',
19?????????? layout:'fit',
20?????????? items: [
21?????????????? {
22?????????????????? xtype:'tabpanel',
23?????????????????? height:80,
24?????????????????? items:[{
25?????????????????????? xtype:'panel',
26?????????????????????? title:'查询表',
27?????????????????????? margin: '5 0 0 20',
28?????????????????????? items:[
29?????????????????????? {
30????????????????????????????? xtype: 'combobox',
31???????????????????????????? width: 219,
32???????????????????????????? id:'combtables',
33???????????????????????????? fieldLabel: '选择表',
34???????????????????????????? labelWidth: 50,
35???????????????????????????? maxWidth: 200,
36???????????????????????????? editable:false,
37???????????????????????????? valueField: 'tablename',
38???????????????????????????? displayField: 'tablename',
39???????????????????????????? store:Ext.create('sxpt.store.admin.Tables'),
40???????????????????????????? labelWidth: 80,
41?
42?????????????????????? }
43?????????????????????? ]
44?????????????????? }
45?????????? ]
46?????? }]
47 });  之后为了每次选择表后就加载数据,在combobox中添加change监听器,实现如下:

?1??????????????????????????? listeners:{
?2???????????????????????????????? change:function(combo, record,index){
?3???????????????????????????????????? var griddb=Ext.getCmp('databaselist');
?4???????????????????????????????????? Ext.Ajax.request({
?5???????????????????????????????????????? url:'admin/admin_database_fieldsa',
?6???????????????????????????????????????? params:{
?7???????????????????????????????????????????? tablename:this.value
?8???????????????????????????????????????? },
?9???????????????????????????????????????? method : 'POST',
10???????????????????????????????????????? success : function(response) {
11???????????????????????????????????????????? var strT=response.responseText;
12????????????????????????????????????????????
13???????????????????????????????????????????? var json = Ext.JSON.decode(strT.replace(//"/{/g,"{").replace(//}/"/g,"}"));??????????????? //替换掉由                                                                 于struts-json序列化产生的多余双引号
14???????????????????????????????????????????? var store=Ext.create('Ext.data.Store',{
15???????????????????????????????????????????????? fields:json.fields,
16???????????????????????????????????????????????? data:json.contentstr
17???????????????????????????????????????????? });
18???????????????????????????????????????????? var pagebar=Ext.getCmp('datapagebar');
19???????????????????????????????????????????? pagebar.bind(store);            //为分页栏加载数据
20???????????????????????????????????????????? store.load();
21???????????????????????????????????????????? griddb.reconfigure(store,json.fieldheader);
22???????????????????????????????????????? }  至此,动态的grid就已经完成了。

三、一个问题

  如果你注意struts—json插件的处理结果的话就会发现,它对String类型的属性序列化是会自动加上引号,如上边字段头格式序列化后为:

"fieldheader":["{text:'rid',dataIndex:'rid',flex:1}","{text:'rname',dataIndex:'rname',flex:1}","{text:'rstring',dataIndex:'rstring',flex:1}"]  但是我们期望的数据格式应该是不带红色引号的。这两者什么区别呢?主要是字符串执行Ext.JSON.decode()后的结果不一样,带引号的反序列化之后fieldheader是一个包含三个字符串的集合(这与服务器端一致,但却并非我们想要的),而不带引号的反序列化之后fieldheader里边包含的是3个对象,每个对象里边包含三个字段,这样的格式才是Extjs可以正确处理的json数据格式。

  因此需要在反序列化之前对接收的字符串进行如下处理:

strT.replace(//"/{/g,"{").replace(//}/"/g,"}")  一下是完成的js代码:

?

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦!?js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

本文固定链接: http://www.js-code.com/js/js_9148.html