EXT的表格组件GRIDPANEL可以说是笔者用过最为强大的组件之一,做为笔者在CSDN博客的处女帖,笔者就给大家介绍下该组件
一、 可能有些同学没使用过Extjs,简单介绍下Ext:
1.1Ext
Ext2.0对框架进行了非常大的重构,其中最重要的就是形成了一个结构及层次分明的组件体系,由这些组件形成了Ext的控件
Ext组件是由 Component类定义,组件可以直接通过new 关键子来创建,比如控件一个窗口,使用newExt.Window(),创建一个表格则使用new Ext.GridPanel()。当然,除了一些普通的组件以外,一般都会在构造函数中通过传递构造参数来创建组件。组件的构造函数中一般都可以包含一个对象,这个对象包含创建组件所需要的配置属性及值,组件根据构造函数中的参数属性值来初始化组件。所有的组件都继承自Ext.Component.
1.2Ext入口
在ExtJS库文件及页面内容加载完后,ExtJS会执行Ext.onReady中指定的函数,因此可以用,一般情况下每一个用户的ExtJS应用都是从Ext.onReady开始的,使用ExtJS应用程序的代码大致如下:
<scripttype="text/javascript">
Ext.onReady(function(){
…
})
</script>
或
<scripttype="text/javascript">
Ext.onReady(extinit);
function extinit(){
…
}
</script>
二、GridPanel的介绍
2.1何为GridPanel
GridPanel:此类系基于Grid控件的一个面板组件,呈现了Grid的主要交互接口。
Store:数据记录的模型(行为单位 )The Model holding the data records (rows)
Columnmodel : 列怎么显示 Column makeup
View: 封装了用户界面 Encapsulates the user interface
Selectionmodel : 选择行为的模型 Selection behavior
2.2使用前先引入类库
主要包括三个大的文件ext-all.css,ext-base.js,ext-all.js,在引用ext类库的时候.这三个文件必不可少(当然你也可以只引用grid对应的js).
<linkrel="stylesheet" type="text/css"href="<%=request.getContextPath()%>/ext_2/resources/css/ext-all.css"/>
<scripttype="text/javascript"src="<%=request.getContextPath()%>/ext_2/adapter/ext/ext-base.js"></script>
<scripttype="text/javascript"src="<%=request.getContextPath()%>/ext_2/ext-all.js"></script>
2.3表头ColumnModel
首先,一个表格应该有列定义,即定义表头ColumnModel,它的默认实现。该类由列配置组成的数组初始化:
var cm = new Ext.grid.ColumnModel([
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex'},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);
注:
header:在Grid头部视图中显示的文字
dataIndex:可选的)数据索引,相当于Grid记录集(Ext.data.Store里面的Ext.data.Record)中字段名称,字段的值用于展示列里面的值(column's value)。 如不指定,Record的数据列中的索引将作为列的索引。
sortable: (可选的)True表示为可在该列上进行排列。默认为defaultSortable属 性的值
renderer:(可选的)该函数用于加工单元格的原始数据,转换成为HTML并返回给GridView进一步处理。
2.4获取数据集
获取数据集,Ext Grid能够支持多种数据类型,如二维数组、Json数据和XML数据,甚至包括我们自定义的数据类型。
Ext为我们提供了一个桥梁Ext.data.Store,通过它我们可以把任何格式的数据转化成grid可以使用的形式,这样就不需要为每种数据格式写一个grid的实现了。
下面简单介绍三种数据的访问:
2.4.1二维数组数据集:
/***********ArrayMemoryProxy***********/
//ArrayData
var data= [
['1','male','name1','descn1'],
['2','male','name1','descn2'],
['3','famale','name3','descn3'],
['4','famale','name4','descn4'],
['5','male','name5','descn5']
];
//ArrayReader
var ds=new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(data),
reader: new Ext.data.ArrayReader({}, [
{name: 'id',mapping: 0},
{name: 'sex',mapping: 1},
{name: 'name',mapping: 2},
{name: 'descn',mapping: 3}
])
});
ds.load();//对数据进行初始化
注:
Proxy: Store对象使用一个DataProxy的实现来访问数据对象。 Proxy是指定要装载的数据和代理形式,即数据获取方式,包含以下三种:
httpproxy:构造一个HttpProxy对象
使用示例:
var proxy=new Ext.data.HttpProxy({url:'foo.jsp'});//jsp
newExt.data.HttpProxy({url:'datasource.xml'});//xml
new Ext.data.HttpProxy({url:‘test?act=page_list_json’})//servlet
scripttagproxy:这个类和HttpProxy类似,也是用于请求远程数据,但能用于跨主域调用
memoryproxy:解析内存中的数据
使用示例:
proxy: newExt.data.MemoryProxy(data)
Reader:
从proxy中读取的数据需要进行解析,这些数据转换成Ext.data.Record数组后才能提供给Ext.data.Store使用。Store对象使用DataReader处理数据对象来返回一个Record对象的数组。有以下三种类型:
ArrayReader:ArrayReader的作用是从二维数组里依次读取数据,然后生成对应的Record。默认情况下是按列顺序读取数组中的数据,不过你也可以考虑用mapping指定record与原始数组对应的列号。ArrayReader的用法很简单,但缺点是不支持分页。
JsonReader:在JavaScript中,JSON是一种非常重要的数据格式,key:value的形式比XML那种复杂的标签结构更容易理解,代码量也更小,很多人倾向于使用它作为EXT的数据交换格式。与数组相比,JSON的最大优点就是支持分页,我们可以使用totalProperty参数表示数据的总量。 successProperty参数是可选的,可以用它判断当前请求是否执行成功,进而判断是否进行数据加载。在不希望JsonReader处理响应数据时,可以把successProperty设置成false。
xmlReader:XmlReader使用的参数与之前介绍的JsonReader有些不同,我们可以看到这里用到了 totalRecords和record两个参数,其中totalRecords用来指定从’totalRecords’标签里获得后台数据总数,record则表示XML中放在record标签里的数据是我们需要显示的结果数据。其他两个参数success和id的含义和JsonReader中对应的参数相似,分别用来判断操是否成功和这次返回的id。因为XML中的标签和reader里需要的名字是相同的,所以简化了配置,将 [{name:’id’},{name:’name’},{name:’descn’}]直接写成了[‘id’,’name’,’descn’]
name:ColumnModel中dataIndex寻找的对象
mapping: mapping属性用于标记data中的读取后的数据与标头的映射关系,一般是不用设置的。但如果我们想让sex的数据中name栏中出现,可以设置mapping值。映射了"descn"字段为行对象的"descn"键
2.4.2 JSON数据集及其解析方式:
data = {
'coders': [
{ 'id': '1','sex': 'male', 'name':'McLaughlin', 'descn': 'brett@newInstance.com' },
{ 'id': '2','sex': 'male','name':'Hunter', 'descn': 'jason@servlets.com' },
{ 'id': '3','sex': 'female','name':'Harold', 'descn': 'elharo@macfaq.com' },
{ 'id': '4','sex': 'male','name':'Harolds', 'descn': 'elhaross@macfaq.com' }
]
};
ds = new Ext.data.Store({
proxy: newExt.data.MemoryProxy(data),
reader: newExt.data.JsonReader({root: 'coders'}, [
{name:'id'}, // 映射了Record的"id" 字段为行对象的同名键名称
{name:'name',mapping:'name'},
{name:'sex',mapping:'sex'},
{name:'descn',mapping:'descn'} // 映射了"descn"字段为行对象的"descn"键
])
});
2.4.3 XML数据集及其解析方式:
/*********XMLMemoryProxy************/
data='<?xml version="1.0"encoding="UTF-8"?>'
+'<dataset>'
+'<results>2</results>'
+'<item>'
+'<id>1</id>'
+'<sex>male</sex>'
+'<name>Taylor</name>'
+'<descn>Coder</descn>'
+'</item>'
+'<item>'
+'<id>2</id>'
+'<sex>famale</sex>'
+'<name>Lucy</name>'
+'<descn>Coder</descn>'
+'</item>'
+'</dataset>';
var xdoc;
if(typeof(DOMParser) =='undefined'){
xdoc = newActiveXObject("Microsoft.XMLDOM");
xdoc.async="false";
xdoc.loadXML(data);
}else{
var domParser = new DOMParser();
xdoc = domParser.parseFromString(data,'application/xml');
domParser = null;
};
ds = new Ext.data.Store({
proxy: newExt.data.MemoryProxy(xdoc),
reader: newExt.data.XmlReader({
totalRecords:'totalRecords',
success: 'success',
record: 'item',
id: "id"
},['id','sex','name','descn'])
});
2.5渲染并展示表格
var grid = new Ext.grid.GridPanel({
renderTo: 'container', //渲染到的容器
title:'Ext Grid Test',
width:450, //Grid需要一个宽度来显示其所有的列,也需要一个高度来滚动列出所有的行。
height:410,
trackMouseOver:false, //True表示为鼠标移动时高亮显示
loadMask: {msg:'正在加载数据,请稍侯……'}, //True表示为当grid加载过程中,会有一个Ext.LoadMask的遮罩效果。默认为false
store: ds,
cm: cm
});
grid.render(); //组件渲染之后触发
注:
采用配置好的Reader格式去加载Record缓存,具体请求的任务由配置好的Proxy对象完成
如果使用服务器分页,那么必须指定在options.params中start和limit两个参数。start参数表明了从记录集(dataset)的哪一个位置开始读取,limit是读取多少笔的记录。Proxy负责送出参数。
2.6容器
<divid='container'></div>
2.7事件
//单元格单击事件
grid.addListener('cellclick', cellclick);
function cellclick(grid, rowIndex,columnIndex, e) {
var record = grid.getStore().getAt(rowIndex); //Get the Record
var fieldName = grid.getColumnModel().getDataIndex(columnIndex); //Getfield name
var data = record.get(fieldName);
Ext.MessageBox.alert('show','当前选中的数据是'+data);
}
注:
其他主要事件:
celldblclick( Grid this, Number rowIndex,Number columnIndex, Ext.EventObject e ) 单元格(cell)被双击时触发。
click( Ext.EventObject e ) 整个Grid被单击的原始事件
dblclick( Ext.EventObject e ) 整个Grid被双击的原始事件。
rowclick( Grid this, Number rowIndex,Ext.EventObject e ) 行(row)被单击时触发
rowdblclick( Grid this, Number rowIndex,Ext.EventObject e ) 行(row)被双击时触发。
2.8其他设置
//选择框以及加工单元格的原始数据
var sm = newExt.grid.CheckboxSelectionModel();//选择框
var cm = newExt.grid.ColumnModel([
new Ext.grid.RowNumberer(),//行编号
sm,//决定了选择框的位置
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex',sortable:true,renderer:function(value){
if(value=='male'){
return " <spanstyle='color:red;font-weight:bold;'>红男</span>";
}else{
return " <spanstyle='color:green;font-weight:bold;'>绿女</span>";
}
}},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);
cm.defaultSortable =true;//defaultSortable属性
//配置视图信息
var view=newExt.grid.GridView({forceFit:true,sortAscText :'正序',sortDescText :'倒序'});
view.columnsText='列显示/隐藏';
sm:sm,
view:view
2.9分页
首先加入面板底部的分页工具条: 此项可以是Ext.Toolbar的实例、工具条的配置对象,或由按钮配置项对象构成的数组,以加入到工具条中。
PagingToolbar: 一个要和Ext.data.Store参与绑定并且自动提供翻页控制的工具栏。
bbar: newExt.PagingToolbar({
pageSize: 20, //每页要展现的记录数(默认为 20)
store: ds, //翻页工具栏应该使用Ext.data.Store作为它的数据源(在需要的时候)。
displayInfo: true, //为true时展示展现信息(默认为false)
displayMsg: '当前显示{0} - {1}条记录 /共{2}条记录', //
emptyMsg: "No topics to display"//没有数据记录的时候所展示的信息(默认为"No data to display")
})
2.9.1 JSON数据集分页:
/********* JSONHttpProxy************/
ds = new Ext.data.Store({
proxy: newExt.data.HttpProxy({url:'page_json.jsp'}), //Proxy对象,用于访问数据对象。
reader: newExt.data.JsonReader(
{
totalProperty:'totalProperty', //该属性是指定记录集的总数(可选的)
root: 'root', //该属性是指定包含所有行对象的数组根节点
idProperty:"id" //该属性是指定每一个行对象中究竟哪一个是记录的ID字段(可选的)
},
[
{name: 'id'},// 映射了Record的"id" 字段为行对象的同名键名称
{name:'name',mapping:'name'},
{name:'sex',mapping:'sex'},
{name:'desc',mapping:'descn'} // 映射了"descn"字段为行对象的"descn"键
]
)
});
ds.load({params:{start:0, limit:20}});
2.9.2 XML数据集分页:
/********* XMLHttpProxy************/
ds = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
//url:'../../test?act=page',
url:'page_xml.jsp',
method:'POST'
}),
reader:new Ext.data.XmlReader({
totalRecords:"totalProperty",
record:"record",
success: 'success',
id: "id",
fields: [
{ name: 'id',mapping: 'id' },
{ name: 'name', mapping: 'name' },
{ name:'sex', mapping: 'sex' },
{ name:'desc', mapping: 'descn' }
]
})
});
2.9.3分页扩展:
7.3扩展:JSON工具包的使用,以及参数的传递
/*********JSON HttpProxyPageList************/
var ds = new Ext.data.Store({
proxy:new Ext.data.HttpProxy({url:'page_jsonlist.jsp?act=page_list_json'}), //Proxy对象,用于访问数据对象。
reader: newExt.data.JsonReader(
{
totalProperty:'totalProperty', //该属性是指定记录集的总数(可选的)
root: 'root', //该属性是指定包含所有行对象的数组根节点
idProperty:"id" //该属性是指定每一个行对象中究竟哪一个是记录的ID字段(可选的)
},
[
{name: 'id'},// 映射了Record的"id" 字段为行对象的同名键名称
{name:'name',mapping:'name'},
{name:'sex',mapping:'sex'},
{name:'descn',mapping:'descn'} // 映射了"descn"字段为行对象的"descn"键
]
)
});
buttons:[{text:"确定",handler:function(){
varproduct_id="product_id1";
varname="name1";
ds.baseParams={product_id:product_id,name:name};
ds.load({params:{start:0,limit:20}});
}},{text:"取消"}]