资源描述
EXTGrid控件精华展现0积分下载.docx
《EXTGrid控件精华展现0积分下载.docx》由会员分享,可在线阅读,更多相关《EXTGrid控件精华展现0积分下载.docx(21页珍藏版)》请在冰豆网上搜索。
![EXTGrid控件精华展现0积分下载.docx](https://file1.bdocx.com/fileroot1/2023-4/24/a1c835d5-3de5-4663-9f68-3dfe2948bbe4/a1c835d5-3de5-4663-9f68-3dfe2948bbe41.gif)
EXTGrid控件精华展现0积分下载
EXTGrid控件精华展现javascript
EXTGrid控件精华展现javascript
EXTGrid控件精华展现javascript
2009-05-0609:
47
无论是界面之美,还是功能之强,ext的表格控件都高居榜首。
单选行,多选行,高亮显示选中的行,推拽改变列宽度,按列排序,这些基本功能咱们就不提了。
自动生成行号,支持checkbox全选,动态选择显示哪些列,支持本地以及远程分页,可以对单元格按照自己的想法进行渲染,这些也算可以想到的功能。
再加上可编辑grid,添加新行,删除一或多行,提示脏数据,推拽改变grid大小,grid之间推拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。
更令人惊叹的是,这些功能竟然都在ext表格控件里实现了。
呵呵~不过ext也不是万能的,与fins的ecside比较,ext不能锁定列(土豆说1.x里支持锁定列,但是2.0里没有了,因为影响效率。
),也没有默认的统计功能,也不支持excel,pdf等导出数据。
另外fins说,通过测试ecside的效率明显优于ext呢。
:
)
2.2.让我们搞一个grid出来耍耍吧。
光说不练不是我们的传统,让我们基于examples里的例子,来自己搞一个grid看看效果,同时也可以知道一个grid到底需要配置些什么东西。
1.首先我们知道表格肯定是二维的,横着叫行,竖着叫列。
跟设计数据库,新建表一样,我们要先设置这个表有几列,每列叫啥名字,啥类型,咋显示,这个表格的骨架也就出来了。
ext里,这个列的定义,叫做ColumnModel,简称cm的就是它,它作为整个表格的列模型,是要首先建立起来的。
这里我们建立一个三列的表格,第一列叫编号(code),第二列叫名称(name),第三列叫描述(descn)。
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id'},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
看到了吧?
非常简单的定义了三列,每列的header表示这列的名称,dataIndex是跟后面的东西对应的,咱们暂且不提。
现在只要知道有了三列就可以了。
2.有了表格的骨架,现在我们要向里边添加数据了。
这个数据当然也是二维了,为了简便,我们学习examples里的array-grid.js里的方式,把数据直接写到js里。
vardata=[
['1','name1','descn1'],
['2','name2','descn2'],
['3','name3','descn3'],
['4','name4','descn4'],
['5','name5','descn5']
];
很显然,我们这里定义了一个二维数据,(什么?
你不知道这是二维数组?
快改行吧,这里不是你该待的地方。
)
这个有五条记录的二维数组,显示到grid里就应该是五行,每行三列,正好对应这id,name,descn,在我们的脑子里应该可以想像出grid显示的结果了,为了让想像变成显示,我们还需要对原始数据做一下转化。
3.因为咱们希望grid不只能支持array,还可以支持json,支持xml,甚至支持咱们自己定义的数据格式,ext为咱们提供了一个桥梁,Ext.data.Store,通过它我们可以把任何格式的数据转化成grid可以使用的形式,这样就不需要为每种数据格式写一个grid的实现了。
现在咱们就来看看这个Ext.data.Store是如何转换array的。
vards=newExt.data.Store({
proxy:
newExt.data.MemoryProxy(data),
reader:
newExt.data.ArrayReader({},[
{name:
'id'},
{name:
'name'},
{name:
'descn'}
])
});
ds.load();
ds要对应两个部分:
proxy和reader。
proxy告诉我们从哪里获得数据,reader告诉我们如何解析这个数据。
现在我们用的是Ext.data.MemoryProxy,它是专门用来解析js变量的。
你可以看到,我们直接把data作为参数传递进去了。
Ext.data.ArrayReader专门用来解析数组,并且告诉我们它会按照定义的规范进行解析,每行读取三个数据,第一个叫id,第二个叫name,第三个descn。
是不是有些眼熟,翻到前面cm定义的地方,哦,原来跟dataIndex是对应的。
这样cm就知道哪列应该显示那条数据了。
唉,你要是能看明白这一点,那你实在是太聪明了。
记得要执行一次ds.load(),对数据进行初始化。
有兄弟可能要问了,要是我第一列数据不是id而是name,第二列数据不是name而是id咋办?
嗯,嗯,这个使用就用mapping来解决。
改改变成这样:
vards=newExt.data.Store({
proxy:
newExt.data.MemoryProxy(data),
reader:
newExt.data.ArrayReader({},[
{name:
'id',mapping:
1},
{name:
'name',mapping:
0},
{name:
'descn',mapping:
2}
])
});
这样如截图所见,id和name两列的数据翻转了。
如此这般,无论数据排列顺序如何,我们都可以使用mapping来控制对应关系,唯一需要注意的是,索引是从0开始的,所以对应第一列要写成mapping:
0,以此类推。
4.哈哈,万事俱备只欠东风,表格的列模型定义好了,原始数据和数据的转换都做好了,剩下的只需要装配在一起,我们的grid就出来了。
vargrid=newExt.grid.Grid('grid',{
ds:
ds,
cm:
cm
});
grid.render();
注意:
上头是ext-1.x的写法,Ext.grid.Grid的第一个参数是渲染的id,对应在html里应该有一个
的东西,这样grid才知道要把自己画到哪里。
创建完grid以后,还要用grid.render()方法,让grid开始渲染,这样才能显示出来。
5.好了,把所有代码组合到一起,看看效果吧。
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id'},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
vardata=[
['1','name1','descn1'],
['2','name2','descn2'],
['3','name3','descn3'],
['4','name4','descn4'],
['5','name5','descn5']
];
vards=newExt.data.Store({
proxy:
newExt.data.MemoryProxy(data),
reader:
newExt.data.ArrayReader({},[
{name:
'id'},
{name:
'name'},
{name:
'descn'}
])
});
ds.load();
vargrid=newExt.grid.Grid('grid',{
ds:
ds,
cm:
cm
});
grid.render();
看看吧,这就是咱们搞出来的grid了。
html例子是lingo-sample/1.1.1目录下的02-01.html,把这个目录copy到ext-1.x的example目录下,就可以直接打开观看效果。
2.3.上边那个是1.x的,2.0稍微有些不同哦
首先,Ext.grid.Grid已经不见了,咱们需要用Ext.grid.GridPanel。
需要传递的参数也有少许区别。
vargrid=newExt.grid.GridPanel({
el:
'grid',
ds:
ds,
cm:
cm
});
看到了吗?
负责指定渲染位置的id放到了{}里边,对应的名字是el。
似乎ext2里对这些参数进行了统一,比以前更整齐了。
因为其他地方都一样,我就不多说了,html例子在是lingo-sample/2.0目录下的02-01.html。
从截图上看,少了斑马条,下边多了一条线,应该只是css有所不同吧。
默认情况下,两个版本的grid都可以拖拽列,也可以改变列的宽度。
不知道怎么禁用这两个功能呢。
最大的不同应该是1.x里默认支持的右键效果,在2.0里不见了。
按shift和ctrl多选行的功能倒是都有。
区别是,全选后,1.x必须按住ctrl才能取消,直接单击其中一个行,不会取消全选功能,而2.0里只需要任意点击一行,就取消全选,只选中刚才点击的那行。
哦,哦,那颜色不要也算是区别吧。
2.4.按顺序,咱们先要把常见功能讲到,让grid支持按列排序
其实很简单,需要小小改动一下列模型。
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id',sortable:
true},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
如果你英语还可以,或者懂得查字典的话(软件翻译也算),那么你就会知道,多出来的这个sortable属性应该是可以排序的意思。
现在咱们试一下改动后的效果。
看到了没有?
编号的标题上有个小小的箭头,表格里的数据也是按照编号做的逆序排列,如此简单,我们就实现了按列排序。
很有趣的是,2.0加上sortable以后,1.x那种右键功能也跑回来了,不过它用的不是右键,而是下拉菜单似的实现方式。
什么?
你问为什么其他两列无法排序?
!
嗯,好像是因为你还没有给另两列添加sortable属性。
怎么加?
!
按编号那样加就行了。
还是不会?
!
-_-。
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id',sortable:
true},
{header:
'名称',dataIndex:
'name',sortable:
true},
{header:
'描述',dataIndex:
'descn',sortable:
true}
]);
这样所有列都可以排序了。
什么?
怎么取消排序?
!
-_-。
2.5.让单元格里显示红色的字,图片,按钮,你还能想到什么?
嘿,希望你跟我一样,不愿意只能在grid里看到文字,至少不是单调的,毫无特色的文字。
有些人就问了,如果我想改变一下单元格里显示内容,应该怎么办呢?
非常不幸的是,ext的作者,伟大的jack早已经想到了,说真的,你没想到的,他都想到了,不只想到了,他还做出来了。
唉,这就是区别啊。
为啥你就不能动手做些东西呢?
就知道向别人要这要那,唉。
首先,我宣布,偶们的数据要扩充啦,每个人要加上一个性别字段。
vardata=[
['1','male','name1','descn1'],
['2','female','name2','descn2'],
['3','male','name3','descn3'],
['4','female','name4','descn4'],
['5','male','name5','descn5']
];
男女搭配,干活不累撒。
而且现在中国就是男多女少,我就还没对象呢。
征婚中,单身女性加(QQ)771490531详谈。
你可以试试不改其他的部分,显示的结果是不会改变的,因为原始数据要经过ds的处理才能被grid使用,那么下一步我们就开始修改ds,把性别加进去。
vards=newExt.data.Store({
proxy:
newExt.data.MemoryProxy(data),
reader:
newExt.data.ArrayReader({},[
{name:
'id'},
{name:
'sex'},
{name:
'name'},
{name:
'descn'}
])
});
添加了一行{name:
'sex'},把数组的第二列映射为性别。
现在grid可以感觉到sex了,嘿嘿。
不过grid还显示不了性别这列,因为咱们还没改cm。
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id'},
{header:
'性别',dataIndex:
'sex'},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
到现在其实都没什么新东西,但是你不觉得光看平板字,很难分出哪个是GG哪个是MM吗?
听说过红男绿女没?
要是男的都加上红色,女的都变成绿色,那不是清楚多了。
就像下面一样。
怎么样?
是不是效果大不同了。
你不会认为很难吧,嗯,确实,如果你对html和css完全搞不明白的话,劝你还是先去学学吧,对自己有信心的往下看。
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id'},
{header:
'性别',dataIndex:
'sex',renderer:
function(value){
if(value=='male'){
return"red;font-weight:
bold;'>红男";
}else{
return"green;font-weight:
bold;'>绿女";
}
}},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
别被吓到,这么一大段其实就是判断是男是女,然后配上颜色。
你要是觉得乱,也可以这么做。
functionrenderSex(value){
if(value=='male'){
return"red;font-weight:
bold;'>红男";
}else{
return"green;font-weight:
bold;'>绿女";
}
}
varcm=newExt.grid.ColumnModel([
{header:
'编号',dataIndex:
'id'},
{header:
'性别',dataIndex:
'sex',renderer:
renderSex},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
实际上这个renderer属性至关重要,它的值是一个function,哦,你说不知道js里function可以这么用?
那么恭喜你,现在你知道了。
renderer会传递个参数进去,咱们grid里看到的,是这个函数的返回值,怎么样,神奇吧?
同志们,你们也应该看到了,返回html就可以,是html啊,html里有的东西,你返回什么就显示什么,颜色,链接,图片,按钮,只要你愿意,整个网页都可以返回回去。
还有什么做不到的?
哦,你不会html,那没辙,回去学吧。
咱们先来个图片。
functionrenderSex(value){
if(value=='male'){
return"red;font-weight:
bold;'>红男";
}else{
return"green;font-weight:
bold;'>绿女";
}
}
是不是太简单了,下面咱们来玩点儿高级的。
functionrenderDescn(value,cellmeta,record,rowIndex,columnIndex,store){
varstr=""这个单元格的值是:
"+value+"\\n"+
"这个单元格的配置是:
{cellId:
"+cellmeta.cellId+",id:
"+cellmeta.id+",css:
"+cellmeta.css+"}\\n"+
"这个单元格对应行的record是:
"+record+",一行的数据都在里边\\n"+
"这是第"+rowIndex+"行\\n"+
"这是第"+columnIndex+"列\\n"+
"这个表格对应的Ext.data.Store在这里:
"+store+",随便用吧。
"+
"\")'>";
returnstr;
}
来看看我们可以在render里用到多少参数:
1.value是当前单元格的值
2.cellmeta里保存的是cellId单元格id,id不知道是干啥的,似乎是列号,css是这个单元格的css样式。
3.record是这行的所有数据,你想要什么,record.data["id"]这样就获得了。
4.rowIndex是行号,不是从头往下数的意思,而是计算了分页以后的结果。
5.columnIndex列号太简单了。
6.store,这个厉害,实际上这个是你构造表格时候传递的ds,也就是说表格里所有的数据,你都可以随便调用,唉,太厉害了。
有个同学就问啦:
EXTrender的参数,是如何得到的呢。
因为你讲的那些都是EXT自己内部的。
它是如何把这些参数传递给render的呢?
这个问题其实比较简单,只是你们想复杂了。
既然是函数,就肯定有调用它的地方,你找到GridView.js在里边搜索一下renderer,就会看到调用render的地方,这些参数都是在这里传进去的。
好,看看效果吧。
剩下的,就是发挥各位聪明才智的时候了,舞台已经搭好,看你如何表演了。
html例子,1.x版本在lingo-sample/1.1.1目录下的02-02.html,2.0的版本在lingo-sample/2.0目录下的02-02.html。
2.6.更进一步,自动行号和多选checkbox
实际上行号和多选checkbox都是renderer的延伸,当然多选checkbox更酷一点儿,两者经常一起使用,所以让我们放在一起讨论好了。
2.6.1.自动行号
只需要在cm中加上一行,这一行不会与ds中的任何数据对应,这也告诉我们可以凭空制作列,哈哈。
在之前的例子上改啦。
varcm=newExt.grid.ColumnModel([
{header:
'NO.',renderer:
function(value,cellmeta,record,rowIndex){
returnrowIndex+1;
}},
{header:
'编号',dataIndex:
'id'},
{header:
'性别',dataIndex:
'sex'},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
如吾等所愿,不指定dataIndex,而是直接根据renderer返回rowIndex+1,因为它是从0开始的,所以加个一。
截图如下。
1.x的例子在lingo-sample/1.1.1/02-03.html
很遗憾的是,2.0里有自己的默认实现了,咱们不能展现自己的手工技艺了,还是乖乖使用jack提供的东东吧。
于是,在2.0里cm就变成了这幅模样。
varcm=newExt.grid.ColumnModel([
newExt.grid.RowNumberer(),
{header:
'编号',dataIndex:
'id'},
{header:
'性别',dataIndex:
'sex'},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
你绝对会同意我的意见,Jack'sworkisamazing.实在是太神奇了。
看看截图就知道。
2.0的例子在lingo-sample/2.0/02-03.html
2.6.2.全选checkbox的时间了,请允许我让2.0先上场。
因为2.0里有checkboxSelectionModel,这样完全可以证实用别人的轮子,比自己造轮子要方便。
而且咱们造的轮子完全没有jack圆。
不信的话,看下面1.x里的实现。
我们一直在修改cm,这次我们也要对它动刀了,不过SelectionModel既sm也要处理一下,这是为了改变单选和多选行的方式,以前这些可以靠shift或ctrl实现,而现在这些都要与checkbox关联上了。
啦啦啦,先看图片,后看代码。
先看看具体多了什么
varsm=newExt.grid.CheckboxSelectionModel();
神奇的是这个sm身兼两职,使用的时候既要放到cm里,也要放到grid中。
代码如下。
varcm=newExt.grid.ColumnModel([
newExt.grid.RowNumberer(),
sm,
{header:
'编号',dataIndex:
'id'},
{header:
'性别',dataIndex:
'sex'},
{header:
'名称',dataIndex:
'name'},
{header:
'描述',dataIndex:
'descn'}
]);
vargrid=newExt.grid.GridPanel({
el:
'grid',
ds:
ds,
cm:
cm,
sm:
sm
});
然后你就可以得到效果啦,代码在lingo-sample/2.0/02-04.html。
2.6.3.1.x时代的全选checkbox。
理论上只需要给cm再加一列,像自动编号那样,不对应数据,只显示checkbo