1、 Data Grid数据表格控件的前世今生
做WEB开发最常见数据展现形式当属数据表格控件莫属了,在AJAX等富客户端框架出现之前,我们都采用Table标签来开发数据表格,传统的Table标签开发的数据展现列表,有很多不好用的地方,例如:每次加载数据都需要刷新页面,分页和排序也需要整界面的刷新,不能调整列大小等等,还有诸多编码不方便的地方,例如需要自己编写分页、排序功能,当然,有盆友会说:“我可以封装为标准标签库”,封装成标签库自然可以解决一部份问题,但实际上代码量也没减少多少。而AJAX客户端框架的出现,很好的解决了这些问题,例如Ext JS、jQuery EasyUI等框架,当然专业的data Grid开源控件有不下100个,但目前笔者用过的最好用的data Grid控件不是Ext JS,不是为Ext JS打广告,我和Ext JS厂商没有任何的关系,纯属个人体验。
我知道大家都喜欢有图有真相的效果
第一步:老生常谈,引入Ext JS开发包
<%@ page pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<%-- 样式文件,加载全部样式 --%>
<link rel="stylesheet" type="text/css" href="<%=path%>/javascript/extjs-4.1.0/resources/css/ext-all.css" />
<%-- ext js 文件 --%>
<script type="text/javascript" src="<%=path%>/javascript/extjs-4.1.0/ext-all.js"></script>
<script type="text/javascript" src="<%=path%>/javascript/extjs-4.1.0/ext-lang-zh_CN.js"></script>
第二步:定义模型
先来总结一下Ext JS控件的开发步骤,基本上所有的数据类控件都是先定义模型,然后定义Store,再然后是定义控件,最后一步是加载数据。
Ext.define('Card', {
extend: 'Ext.data.Model',
fields: [
{name: 'cardNum', type: 'string'},
{name: 'cardName', type: 'string'},
{name: 'maxConsumeSum'},
{name: 'maxConsumeTimes', type: 'int'},
{name: 'minBalance'},
{name: 'maxBalance'},
{name: 'validDays', type: 'int'},
{name: 'discount', type: 'int'},
{name: 'consumeHour', type: 'string'},
{name: 'validSetMeal', type: 'string'},
{name: 'validMachine', type: 'string'},
{name: 'remark', type: 'string'}
]
});
第三步:定义Store
var store = Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
pageSize:limit,
model: 'Card',
proxy: {
type: 'ajax',
url: '<%=request.getContextPath()%>/basicsetting/listCard',
reader : {
type : 'json',
root : 'rows',
totalProperty : 'total'
}
},
autoLoad : true
});
第四步:定义Data Grid
var grid = Ext.create('Ext.grid.Panel', {
title : '卡类型列表',
//header:false//隐藏title
forceFit : true,
stripeRows : true, //斑马线
store : store,
loadMask : {
msg : '正在加载数据,请稍侯……'
},
columns : [ new Ext.grid.RowNumberer(), //行号
{
header : '卡编号',
dataIndex : 'cardNum',
sortable : true
}, {
header : '卡名称',
dataIndex : 'cardName',
sortable : true
}, {
header : '日消费最大金额',
dataIndex : 'maxConsumeSum',
sortable : true
}, {
header : '日消费最大次数',
dataIndex : 'maxConsumeTimes',
sortable : true
}, {
header : '最小卡余额',
dataIndex : 'minBalance',
sortable : true
}, {
header : '最大卡余额',
dataIndex : 'maxBalance',
sortable : true
}, {
header : '有效使用天数',
dataIndex : 'validDays',
sortable : true
}, {
header : '折扣',
dataIndex : 'discount',
sortable : true
}, {
header : '消费时间段',
dataIndex : 'consumeHour',
sortable : true
}, {
header : '可用套餐',
dataIndex : 'validSetMeal',
sortable : true
}, {
header : '可用机器',
dataIndex : 'validMachine',
sortable : true
}, {
header : '备注',
dataIndex : 'remark',
sortable : true
} ],
dockedItems : [ {
xtype : 'pagingtoolbar',
store : store, // same store GridPanel is using
dock : 'bottom',
displayInfo : true
} ],
tbar : [ {
text : '新增',
iconCls : 'employee-add',
handler : function() {
alert('新增');
}
}, {
itemId : 'editCardType',
text : '编辑',
iconCls : 'employee-remove',
handler : function() {
alert('编辑');
},
disabled : true
}, {
itemId : 'removeCardType',
text : '删除',
iconCls : 'employee-remove',
handler : function() {
alert('删除');
},
disabled : true
} ],
listeners : {
'selectionchange' : function() {
this.down('#editCardType').setDisabled(false);
this.down('#removeCardType').setDisabled(false);
}
}
});
store.load({
params : {
start : start,
limit : limit
}
});
store.loadPage(1);
第五步:创建一个视图用于渲染
Ext.create('Ext.container.Viewport', {
layout : 'fit',
renderTo : Ext.getBody(),
items : [ grid ]
});
第六步:编写服务端代码
服务端代码原则上大家可以自行编写,这里我给出一个Struts2框架的例子,根据多年的编程经验,我建议大家尽量用最简单,最通俗易懂,代码量最少的代码完成功能。我曾经供职的一家公司,架构师对项目架构做了过多的封装,导致编写一个简单的功能都要使用很多的代码才能完成,而且阅读和修改都非常困难。一般5行都搞定的功能,非得搞出个20几行才能完成,这不是画蛇添足么?
@Resource
private CardService cardService;
@Resource(name="pageObject")
private PageBean<Card> pageObject;
@Action(value="setCardType",results={@Result(location="cardList.jsp")})
public String queryTest(){
return "success";
}
/**
*
*/
private static final long serialVersionUID = 1L;
@Action(value="listCard",results={@Result(type="json",params={"root","pageObject"})})
public String queryCard(){
pageObject.setTotal(cardService.findAllCards());
List<Card> rows = cardService.queryCard(start, limit);
pageObject.setRows(rows);
return SUCCESS;
}
@JSON(serialize=false)//不被序列化
public CardService getCardService() {
return cardService;
}
public void setCardService(CardService cardService) {
this.cardService = cardService;
}
public PageBean<Card> getPageObject() {
return pageObject;
}
public void setPageObject(PageBean<Card> pageObject) {
this.pageObject = pageObject;
}
用于分页的Bean
package com.mcs.common;
import java.util.List;
import org.springframework.stereotype.Component;
@Component("pageBean")
public class PageBean<T> {
private List<T> rows;
private int total;//总记录数,-1表示未知
public PageBean() {
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<T> getRows() {
return rows;
}
public void setRows(List<T> rows) {
this.rows = rows;
}
}
|
@Action(value="listCard",results={@Result(type="json",params={"root","pageObject"}这个注解中的params参数,是结合了Struts2框架中的json插件进行序列化的,root属性的值pageObject即是你在Action中定义的属性private PageBean<Card> pageObject;