`

让我们搞一个grid出来耍耍吧

    博客分类:
  • Java
阅读更多
功能丰富,无人能出其右

无论是界面之美,还是功能之强,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到底需要配置些什么东西。

首先我们知道表格肯定是二维的,横着叫行,竖着叫列。跟设计数据库,新建表一样,我们要先设置这个表有几列,每列叫啥名字,啥类型,咋显示,这个表格的骨架也就出来了。

ext里,这个列的定义,叫做ColumnModel,简称cm的就是它,它作为整个表格的列模型,是要首先建立起来的。

这里我们建立一个三列的表格,第一列叫编号(code),第二列叫名称(name),第三列叫描述(descn)。

var cm = new Ext.grid.ColumnModel([
    {header:'编号',dataIndex:'id'},
    {header:'名称',dataIndex:'name'},
    {header:'描述',dataIndex:'descn'}
    ]);看到了吧?非常简单的定义了三列,每列的header表示这列的名称,dataIndex是跟后面的东西对应的,咱们暂且不提。现在只要知道有了三列就可以了。

有了表格的骨架,现在我们要向里边添加数据了。这个数据当然也是二维了,为了简便,我们学习examples里的array-grid.js里的方式,把数据直接写到js里。

var data = [
    ['1','name1','descn1'],
    ['2','name2','descn2'],
    ['3','name3','descn3'],
    ['4','name4','descn4'],
    ['5','name5','descn5']
    ];很显然,我们这里定义了一个二维数据, (什么?你不知道这是二维数组?快改行吧,这里不是你该待的地方。)

这个有五条记录的二维数组,显示到grid里就应该是五行,每行三列,正好对应这id,name,descn,在我们的脑子里应该可以想像出grid显示的结果了,为了让想像变成显示,我们还需要对原始数据做一下转化。

因为咱们希望grid不只能支持array,还可以支持json,支持xml,甚至支持咱们自己定义的数据格式,ext为咱们提供了一个桥梁,Ext.data.Store,通过它我们可以把任何格式的数据转化成grid可以使用的形式,这样就不需要为每种数据格式写一个grid的实现了。现在咱们就来看看这个Ext.data.Store是如何转换array的。

var ds = new Ext.data.Store({
    proxy: new Ext.data.MemoryProxy(data),
    reader: new Ext.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来解决。改改变成这样:

var ds = new Ext.data.Store({
    proxy: new Ext.data.MemoryProxy(data),
    reader: new Ext.data.ArrayReader({}, [
    {name: 'id', mapping: 1},
    {name: 'name', mapping: 0},
    {name: 'descn', mapping: 2}
    ])
    });
这样如截图所见,id和name两列的数据翻转了。如此这般,无论数据排列顺序如何,我们都可以使用mapping来控制对应关系,唯一需要注意的是,索引是从0开始的,所以对应第一列要写成mapping:0,以此类推。

哈哈,万事俱备只欠东风,表格的列模型定义好了,原始数据和数据的转换都做好了,剩下的只需要装配在一起,我们的grid就出来了。

var grid = new Ext.grid.Grid('grid', {
    ds: ds,
    cm: cm
    });
    grid.render();注意:上头是ext-1.x的写法,Ext.grid.Grid的第一个参数是渲染的id,对应在html里应该有一个 <div id="grid"></div>的东西,这样grid才知道要把自己画到哪里。

创建完grid以后,还要用grid.render()方法,让grid开始渲染,这样才能显示出来。

好了,把所有代码组合到一起,看看效果吧。

var cm = new Ext.grid.ColumnModel([
    {header:'编号',dataIndex:'id'},
    {header:'名称',dataIndex:'name'},
    {header:'描述',dataIndex:'descn'}
    ]);
    var data = [
    ['1','name1','descn1'],
    ['2','name2','descn2'],
    ['3','name3','descn3'],
    ['4','name4','descn4'],
    ['5','name5','descn5']
    ];
    var ds = new Ext.data.Store({
    proxy: new Ext.data.MemoryProxy(data),
    reader: new Ext.data.ArrayReader({}, [
    {name: 'id'},
    {name: 'name'},
    {name: 'descn'}
    ])
    });
    ds.load();
    var grid = new Ext.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。需要传递的参数也有少许区别。

var grid = new Ext.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支持按列排序

其实很简单,需要小小改动一下列模型。

var cm = new Ext.grid.ColumnModel([
{header:'编号',dataIndex:'id',sortable:true},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);如果你英语还可以,或者懂得查字典的话(软件翻译也算),那么你就会知道,多出来的这个sortable属性应该是可以排序的意思。现在咱们试一下改动后的效果。



看到了没有?编号的标题上有个小小的箭头,表格里的数据也是按照编号做的逆序排列,如此简单,我们就实现了按列排序。

很有趣的是,2.0加上sortable以后,1.x那种右键功能也跑回来了,不过它用的不是右键,而是下拉菜单似的实现方式。


什么?你问为什么其他两列无法排序?!嗯,好像是因为你还没有给另两列添加sortable属性。

怎么加?!按编号那样加就行了。

还是不会?!-_-。

var cm = new Ext.grid.ColumnModel([
{header:'编号',dataIndex:'id',sortable:true},
{header:'名称',dataIndex:'name',sortable:true},
{header:'描述',dataIndex:'descn',sortable:true}
]);这样所有列都可以排序了。什么?怎么取消排序?!-_-。

2.5. 让单元格里显示红色的字,图片,按钮,你还能想到什么?

嘿,希望你跟我一样,不愿意只能在grid里看到文字,至少不是单调的,毫无特色的文字。有些人就问了,如果我想改变一下单元格里显示内容,应该怎么办呢?

非常不幸的是,ext的作者,伟大的jack早已经想到了,说真的,你没想到的,他都想到了,不只想到了,他还做出来了。

唉,这就是区别啊。为啥你就不能动手做些东西呢?就知道向别人要这要那,唉。

首先,我宣布,偶们的数据要扩充啦,每个人要加上一个性别字段。

var data = [
['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,把性别加进去。

var ds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(data),
reader: new Ext.data.ArrayReader({}, [
{name: 'id'},
{name: 'sex'},
{name: 'name'},
{name: 'descn'}
])
});添加了一行{name: 'sex'},把数组的第二列映射为性别。现在grid可以感觉到sex了,嘿嘿。

不过grid还显示不了性别这列,因为咱们还没改cm。

var cm = new Ext.grid.ColumnModel([
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex'},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);到现在其实都没什么新东西,但是你不觉得光看平板字,很难分出哪个是GG哪个是MM吗?听说过红男绿女没?要是男的都加上红色,女的都变成绿色,那不是清楚多了。就像下面一样。


怎么样?是不是效果大不同了。你不会认为很难吧,嗯,确实,如果你对html和css完全搞不明白的话,劝你还是先去学学吧,对自己有信心的往下看。

var cm = new Ext.grid.ColumnModel([
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex',renderer:function(value){
if (value == 'male') {
return "<span style='color:red;font-weight:bold;'>红男</span>";
} else {
return "<span style='color:green;font-weight:bold;'>绿女</span>";
}
}},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);别被吓到,这么一大段其实就是判断是男是女,然后配上颜色。你要是觉得乱,也可以这么做。

function renderSex(value) {
if (value == 'male') {
return "<span style='color:red;font-weight:bold;'>红男</span>";
} else {
return "<span style='color:green;font-weight:bold;'>绿女</span>";
}
}
var cm = new Ext.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,那没辙,回去学吧。

咱们先来个图片。


function renderSex(value) {
if (value == 'male') {
return "<span style='color:red;font-weight:bold;'>红男</span><img src='user_male.png' />";
} else {
return "<span style='color:green;font-weight:bold;'>绿女</span><img src='user_female.png' />";
}
}是不是太简单了,下面咱们来玩点儿高级的。

function renderDescn(value, cellmeta, record, rowIndex, columnIndex, store) {
var str = "<input type='button' value='查看详细信息' onclick='alert(\"" +
"这个单元格的值是:" + value + "\\n" +
"这个单元格的配置是:{cellId:" + cellmeta.cellId + ",id:" + cellmeta.id + ",css:" + cellmeta.css + "}\\n" +
"这个单元格对应行的record是:" + record + ",一行的数据都在里边\\n" +
"这是第" + rowIndex + "行\\n" +
"这是第" + columnIndex + "列\\n" +
"这个表格对应的Ext.data.Store在这里:" + store + ",随便用吧。" +
"\")'>";
return str;
}来看看我们可以在render里用到多少参数:

value是当前单元格的值

cellmeta里保存的是cellId单元格id,id不知道是干啥的,似乎是列号,css是这个单元格的css样式。

record是这行的所有数据,你想要什么,record.data["id"]这样就获得了。

rowIndex是行号,不是从头往下数的意思,而是计算了分页以后的结果。

columnIndex列号太简单了。

store,这个厉害,实际上这个是你构造表格时候传递的ds,也就是说表格里所有的数据,你都可以随便调用,唉,太厉害了。

有个同学就问啦:EXT render的参数,是如何得到的呢。因为你讲的那些都是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中的任何数据对应,这也告诉我们可以凭空制作列,哈哈。

在之前的例子上改啦。

var cm = new Ext.grid.ColumnModel([
{header:'NO.',renderer:function(value, cellmeta, record, rowIndex){
return rowIndex + 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就变成了这幅模样。

var cm = new Ext.grid.ColumnModel([
new Ext.grid.RowNumberer(),
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex'},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);你绝对会同意我的意见,Jack's work is amazing.实在是太神奇了。看看截图就知道。


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关联上了。

啦啦啦,先看图片,后看代码。


先看看具体多了什么

var sm = new Ext.grid.CheckboxSelectionModel();神奇的是这个sm身兼两职,使用的时候既要放到cm里,也要放到grid中。代码如下。

var cm = new Ext.grid.ColumnModel([
new Ext.grid.RowNumberer(),
sm,
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex'},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);
var grid = new Ext.grid.GridPanel({
el: 'grid',
ds: ds,
cm: cm,
sm: sm
});然后你就可以得到效果啦,代码在lingo-sample/2.0/02-04.html。

2.6.3. 1.x时代的全选checkbox。

理论上只需要给cm再加一列,像自动编号那样,不对应数据,只显示checkbox就可以了。难点就是checkbox与某一行被选择的时候要对应上,用checkbox选择上,sm里也要让这一行被选中,反之亦然。嗯,估计会比较复杂呢。

先放上显示checkbox的代码和截图:

var cm = new Ext.grid.ColumnModel([
{header:'NO.',renderer:function(value, cellmeta, record, rowIndex){
return rowIndex + 1;
}},
{header:'<input type="checkbox" onclick="selectAll(this)">',renderer:function(value, cellmeta, record, rowIndex){
return '<input type="checkbox" name="cb">';
}},
{header:'编号',dataIndex:'id'},
{header:'性别',dataIndex:'sex'},
{header:'名称',dataIndex:'name'},
{header:'描述',dataIndex:'descn'}
]);
与sm对接的方面比较麻烦,好在extjs.com上已经有扩展了,或者你可以看看我们弄下来的。 看看1.x多选树的截图。

2.7. 分页了吗?分页了吗?如果还没分就看这里吧。

如果你有一千条信息,一次都输出到grid里,然后让客户用下拉条一点儿一点儿去找吧。我们这里可是要做一个分页效果了,不用滚动屏幕,或者滚动一下就可以看到本页显示的数据,如果想看其他的只需要翻页就可以了。同志们,加强客户体验呀。

实际上,grid控件挺耗性能的,据土豆讲一个页面上放3个grid就可以感觉到响应变慢,以前看过介绍,grid里显示数据过多,听说是上千条,也会明显变慢。

所以说分页是必不可少滴,而且jack提供了方便集成分页工具条的方式,不用一下实在是太浪费了。

两步走,让grid集成分页。

2.7.1. 表面工作,先把分页工具条弄出来。


从图片可以清晰的看到,在grid下边多出来一行东东,包括了前一页,后一页,第一页,最后一页,刷新,以及提示信息。而我们不过写了如下几行代码而已,神奇呀。

var gridFoot = grid.getView().getFooterPanel(true);
var paging = new Ext.PagingToolbar(gridFoot, ds, {
pageSize: 10,
displayInfo: true,
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
emptyMsg: '没有记录'
});首先使用grid.getView().getFootPanel(true),获得grid下边那一条,嘿嘿,人家grid就设计的这么好,脚底下专门留了地方让你放东西。我们老实不客气,把Ext.PagingToolbar放到上边,就可以显示分页工具条了。

这分页工具条可不是个摆设,你按了前一页,后一页,整个grid都要有反应才对,要不咱们费劲弄这个么东西过来干嘛呀?所以,我们在构造PagingToolbar的时候,不但告诉它,在gridFoot上显示,还告诉它,进行分页跳转的时候,要对ds也进行操作。这个ds就是grid用来获取和显示数据的,它一变整个grid都发生变化,嘿嘿~这就算共享数据模型了。厉害呀。

知道了分页的玄机,让我们揉揉眼睛,好好看看里边的参数。

pageSize,是每页显示几条数据。

displayInfo,跟下面的配置有关,如果是false就不会显示提示信息。

displayMsg,只有在displayInfo:true的时候才有效,用来显示有数据的时候的提示信息,中国人应该看得懂汉语,到时候{0},{1},{2}会自动变成对应的数据,咱们只需要想办法把话说通就行了。

emptyMsg,要是没数据就显示这个,jack实在太贴心了,连这些小处都考虑得如此精细。

最好要注意的是,这段代码必须放在grid.render()之后,估计是因为动态生成grid的dom后,才能获得对应的footPanel。

现在给出例子,1.x的例子在lingo-sample/1.1.1/02-05.html。

2.7.2. 2.0赐予我们更大的灵活性

其实,在下,一直,对于:必须先渲染grid才能获得footPanel这事非常愤恨,你想啊,本来分页也应该属于初始化的一部分,现在却要先初始化grid,配置完毕,渲染,回过头来再从grid里把footPanel拿出来,再咕哝分页的配置。真,真,真郁闷呀。

所以2.0里的方式,简直大快民心。

var grid = new Ext.grid.GridPanel({
el: 'grid',
ds: ds,
cm: cm,
bbar: new Ext.PagingToolbar({
pageSize: 10,
store: ds,
displayInfo: true,
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
emptyMsg: "没有记录"
})
});
ds.load();嘿嘿,加一个bbar的参数就可以了,bbar就是bottom bar啦,底端工具条。


不过还是要注意一点,与1.x中不同的是,如果配置了分页工具条,ds.load()就必须在构造grid以后才能执行,否则分页工具条会不起作用。看来分页工具条会把自己和ds做一些关联,来完成与grid共享数据模型的。

对了,还有一点不同,1.x中分页条不会随着浏览器的大小改变,自动放缩,这点在2.0中也解决了。

2.0的例子在lingo-sample/2.0/02-05.html。

2.7.3. 迫不得已,要加上后台脚本了。

grid会每次都显示ds中所有的数据,咱们没法利用静态数据好好演示分页,于是,必须写后台脚本,让ext与后台进行数据交互才能看到真实的分页效果。

咱们尽量在原来的基础上修改啊,把注意力集中在关键部位,一次性突破。

我不会其他语言,后台就用jsp写啦。有个好消息是只要返回的数据格式一样,ext才不管后台是什么写的呢。也就是这样,不管你以后用什么实现后台,前台的ext代码都一样。

<%
String start = request.getParameter("start");
String limit = request.getParameter("limit");
try {
int index = Integer.parseInt(start);
int pageSize = Integer.parseInt(limit);
String json = "{totalProperty:100,root:[";
for (int i = index; i < pageSize + index; i++) {
json += "{id:" + i + ",name:'name" + i + "',descn:'descn" + i + "'}";
if (i != pageSize + index - 1) {
json += ",";
}
}
json += "]}";
response.getWriter().write(json);
} catch(Exception ex) {
}
%>下面我们来解读这段jsp代码:

在进行操作之前,我们先要获得ext传递过来的两个参数:start和limit,start指的从第几个数据开始显示,limit是说从start开始,一共要用多少个数据,当然返回的数据可能会小于这个值。

咱们在后台模拟对100条数据进行分页,在获得了start和limit之后再生成json格式的数据。

何谓json?在理论讲解之前先看看实例,让我们能有个感性认识,至于以后能不能升华到理性认识,就看各位的悟性了。

模拟ext访问后台,并传递两个参数start=0&limit=10,把获得的数据稍微整理一下,是这个样子。

{totalProperty:100,root:[
    {id:0,name:'name0',descn:'descn0'},
    {id:1,name:'name1',descn:'descn1'},
    {id:2,name:'name2',descn:'descn2'},
    {id:3,name:'name3',descn:'descn3'},
    {id:4,name:'name4',descn:'descn4'},
    {id:5,name:'name5',descn:'descn5'},
    {id:6,name:'name6',descn:'descn6'},
    {id:7,name:'name7',descn:'descn7'},
    {id:8,name:'name8',descn:'descn8'},
    {id:9,name:'name9',descn:'descn9'}
    ]}请记住这个数据格式,不管后台是什么,只要满足了这样的格式要求,ext就可以接收处理,显示到grid中。

我这里就不好好介绍json,现在只需要知道json里头除了name(名称)就是value(值),值有好几种格式,如果是数字就不用加引号,如果加了引号就是字符串,如果用[]包裹就是数组,如果出现{}就说明是嵌套的json。诸如此类。

简单瞄了json一眼,开头就是totalProperty:100,这告诉ext:“俺这里有100个数据呢。”,然后就是root:[],root对应着一个数组,数组里有10个对象,每个对象都有id呀,name呀,descn呀。这10个数据最后就应该显示到表格里。

jsp里用for循环生成root数组里的数据,这样我们翻页的时候可以看到数据的变化,要不每次都是一样的数据,你怎么知道翻页是不是起作用了呢?

最后我们把得到的json字符串输出到response里,ext也就可以获得这些数据了。

结果经过了一番折腾,我们的jsp已经确定可以返回我们所需要的数据了。现在我们可以忘掉后台是用什么语言写的了,直接切入ext代码,看看它是怎么样才能跑去后台获得这些数据呢?

因为引入了json作为数据传输格式,这次我们要对ext代码进行一次大换血了,请做好思想准备。

换掉proxy,别在内存里找了,让我们通过http获得我们想要的。

proxy: new Ext.data.HttpProxy({url:'grid.jsp'}),创建HttpProxy的同时,用url这个参数指定咱们去哪里取数据,我们这里设置成grid.jsp,就是我们刚才讨论的jsp脚本啦。

已经不是数组了,现在要用json咯。

reader: new Ext.data.JsonReader({
    totalProperty: 'totalProperty',
    root: 'root'
    }, [
    {name: 'id'},
    {name: 'name'},
    {name: 'descn'}
    ])看比ArrayReader多了什么?totalProperty对应咱们jsp返回的totalProperty,也就是数据的总数。root对应咱们jsp返回的root,就是一个包含返回数据的数组。

好了,最后在初始化的时候,告诉我们希望获得哪部分的数据就可以了。

ds.load({params:{start:0,limit:10}});就在ds读取的时候添加两个参数,start和limit,告诉后台,我们从第一个数可以取起,最多要10个。

在这里有一个小插曲,如果你按照我们以前的设置,grid是无法正常显示的,因为ds.load()无法在grid.render()前准备好所有数组,所以它不知道自己应该实现多高。没法子,我们只好为它指定一个固定的高度了。像这样<div id="grid" style="height:265px;"></div>。

最后,我们就可以使用分页条上那些按钮试试分页了。呵呵~就这么简单。

1.x的例子在lingo-sample/1.1.1/02-06.html,jsp文件在lingo-sample/1.1.1/grid.jsp,下面是它的截图:


有趣的是,1.x中,不需要为div指定高度,它自己就知道如何显示,不晓得为什么2.0里不这样做呢。

2.0的例子在lingo-sample/2.0/02-06.html,jsp文件在lingo-sample/2.0/grid.jsp,下面是它的截图:


2.7.4. 其实分页不一定要踩在脚下,也可以顶在头上。

我的意思是,grid除了FootPanel以外,还有HeaderPanel,意思就是头顶上的面板。我们把分页条放在上面也不会有任何问题。1.x中的代码仅仅是将getFooterPanel改成getHeaderPanel,这样分页条就跑到上头去了。

var gridHead = grid.getView().getHeaderPanel(true);
var paging = new Ext.PagingToolbar(gridHead, ds, {
pageSize: 10,
displayInfo: true,
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
emptyMsg: '没有记录'
});
1.x的例子可以在lingo-sample/1.1.1/02-07.html找到。

2.0就更简单了,只需要改一个字母,b -> t,呵呵~,让原来的bbar(bottom bar)变成tbar(top bar)就可以让我们的工具条登天了。

var grid = new Ext.grid.GridPanel({
el: 'grid',
ds: ds,
cm: cm,
tbar: new Ext.PagingToolbar({
pageSize: 10,
store: ds,
displayInfo: true,
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
emptyMsg: "没有记录"
})
});
2.0的例子可以在lingo-sample/2.0/02-07.html找到。

呃,当然你可以让上下都加上分页条,反正它们最后都是共享一个ds,功能不会有任何问题哈。吼吼。

2.8. 可编辑表格,改变大小,表格间拖拽,树与表格间拖拽。
分享到:
评论

相关推荐

    EXT2.0中文教程

    2.2. 让我们搞一个grid出来耍耍吧。 2.3. 上边那个是1.x的,2.0稍微有些不同哦 2.4. 按顺序,咱们先要把常见功能讲到 2.4.1. 自主决定每列的宽度 2.4.2. 让grid支持按列排序 2.5. 让单元格里显示红色的字,图片,...

    掏钱学Ext(完整版) 附全部源码

    2.2. 让我们搞一个grid出来耍耍吧。 2.3. 上边那个是1.x的,2.0稍微有些不同哦 2.4. 按顺序,咱们先要把常见功能讲到,让grid支持按列排序 2.5. 让单元格里显示红色的字,图片,按钮,你还能想到什么? 2.6. ...

    Ext 开发指南 学习资料

    2.2. 让我们搞一个grid出来耍耍吧。 2.3. grid默认自带的功能 2.4. 按顺序,咱们先要把常见功能讲到 2.4.1. 自主决定每列的宽度 2.4.2. 让grid支持按列排序 2.4.3. 中文排序是个大问题 2.5. 让单元格里显示红色的字...

    wpf的grid自动生成列-删除列(外层grid的一行里生成一个grid)

    在一个外层grid列里生成一个grid布局的内容。比如,某班某人的各科成绩。外层是某人的信息,在这个一行里,有他的语数外三科(一个几行几列的grid)的成绩。 不是为了利益大众,是为了自己,也当做自己曾经写的一个...

    grid嵌套grid

    当我们需要在一个`Grid`中展示的数据本身具有层次结构时,可以使用`Grid`嵌套`Grid`的方法。例如,一个`Grid`显示公司的部门,每个部门下面又包含多个员工,此时,部门可以作为父`Grid`,员工作为子`Grid`进行嵌套。...

    Sigma-Grid.zip_grid_grid jquery_html jquery_jquery grid

    Sigma Grid 是一个基于 jQuery 的数据网格插件,用于在网页中展示和操作表格数据。它提供了丰富的功能,如分页、排序、过滤、编辑等,适用于各种数据密集型的Web应用。这个压缩包包含了关于 Sigma Grid 的使用指南和...

    .net C# PropertyGrid 显示下拉列表

    首先,我们需要添加一个引用 System.Windows.Forms.Design.IWindowsFormsEditorService,以便使用 PropertyGrid 控件。然后,我们定义了一个私有变量 m_selectStr 来存储选择的字段,这些字段用 "|" 隔开。 接下来...

    Grid布局综合Demo案例

    网格布局(Grid布局)是CSS3中的一个强大工具,它为网页设计提供了二维的、基于网格的布局系统,使得在创建复杂且响应式的页面布局时更加灵活和有序。本综合Demo案例将深入探讨如何利用Grid布局来实现各种复杂的网页...

    一个基于C# +VS2008实现的PropertyGrid高级扩展控件源码

    标题提到的"一个基于C# + VS2008实现的PropertyGrid高级扩展控件源码",意味着这是一份自定义的PropertyGrid控件,可能包含了对默认控件功能的增强或定制,以满足特定的开发需求。开发者可能通过以下几种方式来扩展...

    gt-grid的一个例子

    在这个“gt-grid的一个例子”中,我们将深入探讨如何使用`gt-grid`的基本功能,并通过实际代码示例来理解其工作原理。 首先,`gt-grid` 提供了灵活的数据绑定机制,可以方便地将后台数据源与前端表格进行对接。在...

    PropertyGrid 二级联动

    在.NET框架中,`PropertyGrid`控件是一个强大的工具,用于显示和编辑对象的属性。它通常用于创建用户友好的配置界面,允许用户通过一种直观的方式查看和修改对象的属性。在某些应用场景中,我们可能需要实现更复杂的...

    Delphi自定义Grid控件

    在本篇文章中,我们将深入探讨如何在DELPHI7.0下创建一个具有自定义功能的Grid控件,包括自定义查询、点击标题排序、打印内容以及支持添加、修改和更新数据,同时利用右键菜单增强用户交互。 首先,我们需要了解...

    一个很好的EXTGRID实例

    在"一个很好的EXTGRID实例"中,我们可以看到一个BS(Browser/Server)架构的应用,它采用EXT GRID作为用户界面的核心部分,用于显示和管理人员信息。BS架构意味着大部分业务逻辑和数据显示都在浏览器端处理,而...

    C# PropertyGrid控件的分成 多层 折叠 和绑定自定义控件

    例如,假设我们有一个自定义控件`CustomControl1`,我们希望在PropertyGrid中显示和编辑它。我们首先创建一个`CustomControl1Editor`类,继承自`UITypeEditor`,并覆盖其`EditValue`方法。在`EditValue`方法中,我们...

    C# 自定义属性在propertyGrid控件中显示 演示demo

    例如,如果我们想让`Age`属性以年龄范围的形式显示,可以创建一个`AgeRangeConverter`和`AgeRangeEditor`: ```csharp public class AgeRangeConverter : TypeConverter { // 实现转换逻辑... } public class ...

    一个关于C# PropertyGrid增加自定义属性的范例。

    在这个范例中,可能包含了一个名为`CtrlSoft.Collections`的库,这个库可能提供了与集合相关的类型,而我们要在`PropertyGrid`中展示和编辑这些集合。通过上述方式,我们可以确保`PropertyGrid`正确地显示和处理这些...

    PropertyGrid 的相关用法

    例如,在一个文件管理系统中,我们可能需要让用户选择一个文件夹。为了实现自定义下拉框,我们需要创建一个继承自 UITypeEditor 的类,并重写其 GetEditStyle 和 EditValue 方法。 在上面的代码中,我们定义了一个...

    PropertyGrid的三种使用方法

    `Propertygrid_Datatable.rar`可能包含一个例子,演示如何加载一个`DataTable`到`PropertyGrid`,让用户可以查看和修改表的结构。 在实际开发中,选择哪种方法取决于需求。`PropertyBag`适合处理不确定或动态的数据...

    propertyGrid 属性处理演示demo

    在.NET框架中,`PropertyGrid`控件是一个强大的工具,用于显示和编辑对象的属性。这个控件在设计时和运行时都非常有用,因为它能够自动生成一个用户界面,该界面可以展示任何对象的属性,并允许用户进行交互式编辑。...

Global site tag (gtag.js) - Google Analytics