[Ext JS 4] Grid 实战之分页功能

前言

分页功能的实现有两种途径:

一种是服务端分页方式, 也就是web客户端传递页码参数给服务端,服务端根据页面参数返回指定条数的数据。也就是要多少取多少。这种方式比较适合Grid  的数据量很大,需分批取。

另一种是客户端分页方式, 一次性从服务端取回所有的数据在客户端这边实现分页。这种自然适合数据量较少的状况,减少和服务端的交互, 对性能有一些帮助。这种方式还有一种好处就是对于初学Ext JS Grid 或分页功能比较简单和直观了。

Ext 目前的官方文档中,对于客户端分页的方式介绍和实例不多,而服务端的方式,跟具体的服务端的技术相关,Ext 也就没做太多的介绍了。

本篇先介绍分页实现的思想,然后从客户端的实现方式介绍开始,毕竟测试起来简单一些;最后介绍服务端的方式。


分页的效果:



Grid Panel 分页实现思想

要在Grid上实现分页功能,

首先要给这个Grid Panel 添加一个 Ext.PagingToolbar

添加的方式可以使用 bbar 的config 添加到button bar

也可以使用dockedItems 的 config 添加

类似:

 

bbar: Ext.create('Ext.PagingToolbar',{
	    	store: store,
	    	displayInfo: true,
            displayMsg: 'Displaying topics {0} - {1} of {2}',
            emptyMsg: "No topics to display",
          }
         ),


或是:

 

 

dockedItems: [{
	        xtype: 'pagingtoolbar',
	        store: store,   // same store GridPanel is using
	        dock: 'bottom',
	        displayInfo: true
	    }]


使用Ext.create 或是直接在 [] config 都可以。

 

接下来就是这个store 的处理了。page 的store和一般的store 会有一些差别的地方,下面会介绍到。


客户端分页方式(local data)

Ext JS 中将客户端的分页也叫“local data‘ 的分页。

在Ext JS 的官方文档中有提到关于PageingStore这样一篇介绍

Ext.ux.data.PagingStore .

这种方式通过添加一些新的Class 的方式实现。而且这个扩展包是针对Ext js 3.x 来实现的, 需要下载扩展包。

而这篇介绍里的下载link 有需要权限。总之, 有点麻烦。

在Ext JS 4的新版本中,完全可以不用这种方式。

Ext JS API 中有以下这个Class, 用它构造的store 就可以实现分页效果了。

Ext.ux.data.PagingMemoryProxy   proxy: pagingmemory

需要特别注意的是 Ext 的导入包中ext-all.js 并没包含这个类, 看上去这个是作为扩展包。

所以使用前需要导入这个包的 定义js 文件,或是使用Ext 的动态载入方式导入。


直接看例子:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

<script type="text/javascript" src="../lib/extjs/ext-all.js"></script>
<script type="text/javascript" src="../lib/extjs/ux/data/PagingMemoryProxy.js"></script>

<link rel="stylesheet" type="text/css" href="../lib/extjs/resources/ext-theme-neptune/ext-theme-neptune-all.css" />

<script type="text/javascript">

Ext.onReady(function(){
	
	var itemsPerPage = 4;
	var store = Ext.create('Ext.data.Store', {
	    fields:['name', 'email', 'phone'],
	    pageSize: itemsPerPage,
	    proxy: {
	        type: 'pagingmemory',
	        data: [
	                     	        { 'name': 'ALisa',  "email":"lisa@simpsons.com",  "phone":"555-111-1224"  },
	                    	        { 'name': 'Bart',  "email":"bart@simpsons.com",  "phone":"555-222-1234" },
	                    	        { 'name': 'Homer', "email":"home@simpsons.com",  "phone":"555-222-1244"  },
	                    	        { 'name': 'Marge', "email":"marge@simpsons.com", "phone":"555-222-1254"  },
	                    	        { 'name': 'Lisa',  "email":"lisa@simpsons.com",  "phone":"555-111-1224"  },
	                    	        { 'name': 'Bart',  "email":"bart@simpsons.com",  "phone":"555-222-1234" },
	                    	        { 'name': 'Homer', "email":"home@simpsons.com",  "phone":"555-222-1244"  },
	                    	        { 'name': 'Lisa',  "email":"lisa@simpsons.com",  "phone":"555-111-1224"  },
	                    	        { 'name': 'Bart',  "email":"bart@simpsons.com",  "phone":"555-222-1234" },
	                    	        { 'name': 'Homer', "email":"home@simpsons.com",  "phone":"555-222-1244"  },
	                    	        { 'name': 'Marge', "email":"marge@simpsons.com", "phone":"555-222-1254"  }
	       ]
	    }
	});	
	
	store.loadPage(1);
	
	Ext.create('Ext.grid.Panel', {
	    title: 'Simpsons',
	    store: store,
	    columns: [
	        { text: 'Name',  dataIndex: 'name' },
	        { text: 'Email', dataIndex: 'email', flex: 1 },
	        { text: 'Phone', dataIndex: 'phone' }
	    ],
	    height: 200,
	    width: '100%',
	    dockedItems: [{
	        xtype: 'pagingtoolbar',
	        store: store,   // same store GridPanel is using
	        dock: 'bottom',
	        displayInfo: true
	    }],
	    renderTo: Ext.getBody()
	});


});
</script>

</head>
<body>

</body>
</html>

需要说明的:

 

1.一定要导入PagingMemoryProxy.js 

<script type="text/javascript" src="../lib/extjs/ux/data/PagingMemoryProxy.js"></script>

也可以使用动态导入的方式(先设置允许动态导入和导入的文件路径,接着使用require 方式导入)

 

Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux', 'lib/extjs/ux');
Ext.require([
             'Ext.ux.data.PagingMemoryProxy'
         ]);


2. store 的proxy 里的type一定要是 'pagingmemory'。 如果要是按照一般的store 方式定义。

 

则在页面上 toolbar 会有, 但是一次会把所有数据显示出来, 翻页就没什么效果了。


服务器端分页方式

服务器端的分页方式和客户端比较起来,差别仅仅在store 的定义上。

添加的PagingToolbar有前进或后退按钮,点击的时候是会把页面的一些信息通过url 传递到服务端。类似 ?_dc=1374646308167&page=2&start=4&limit=4

以jsp 来说,就可以通过request.getParameter得到这些值了。

String sPage = request.getParameter("page");
String sStart = request.getParameter("start");
String sLimit = request.getParameter("limit");

有了这些值,就可以在服务端做一些过滤了, 看例子:有两个文件

testPageGrid.html

pageGridData.jsp  -- jsp 输出服务端数据

 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

<script type="text/javascript" src="../lib/extjs/ext-all.js"></script>
<link rel="stylesheet" type="text/css" href="../lib/extjs/resources/ext-theme-neptune/ext-theme-neptune-all.css" />
<script>

Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux', '../lib/extjs/ux');
Ext.require([
             'Ext.ux.data.PagingMemoryProxy'
         ]);
         
Ext.onReady(function(){
	var itemsPerPage = 4;
	var store = Ext.create('Ext.data.Store', {
	    fields:['name', 'email', 'phone'],
	    pageSize: itemsPerPage,
	    proxy: {
            type: 'ajax',
            url: 'pageGridData.jsp',
            reader: {
                root: 'items',
                totalProperty: 'totalCount'
            }
	    }	    
	});	
	
	store.loadPage(1);
	
	Ext.create('Ext.grid.Panel', {
	    title: 'Simpsons',
	    store: store,
	    columns: [
	        { text: 'Name',  dataIndex: 'name' },
	        { text: 'Email', dataIndex: 'email', flex: 1 },
	        { text: 'Phone', dataIndex: 'phone' }
	    ],
	    height: 200,
	    width: '100%',
	    dockedItems: [{
	        xtype: 'pagingtoolbar',
	        store: store,   // same store GridPanel is using
	        dock: 'bottom',
	        displayInfo: true
	    }],
	    renderTo: Ext.getBody()
	});
	
});
</script>
</head>
<body>

</body>
</html>

 

<%
response.setContentType( "text/html; charset=UTF-8" );

//page=2&start=4&limit=4
String sPage = request.getParameter("page");
String sStart = request.getParameter("start");
String sLimit = request.getParameter("limit");
int iPage = Integer.valueOf(sPage);
int iStart = Integer.valueOf(sStart);
int iLimit = Integer.valueOf(sLimit);
int totalCount = 12;

StringBuffer dataBuffer = new StringBuffer();
dataBuffer.append("{totalCount:'").append(totalCount).append("',");
dataBuffer.append("items:[");

for(int i =0;i<iLimit;i++)
{
	dataBuffer.append("{");
	String name = "jack_"+sPage+"_"+String.valueOf(i);
	String mail = "jack"+sPage+"_"+String.valueOf(i)+"@email.com";
	String phone = "000-"+sPage+"_"+String.valueOf(i);
	dataBuffer.append("name:'"+name+"',");
	dataBuffer.append("email:'"+mail+"',");
	dataBuffer.append("phone:'"+phone+"'");
	dataBuffer.append("}");
	if(i<iLimit-1)
	{
		dataBuffer.append(",");
	}
}

dataBuffer.append("]");
dataBuffer.append("}");
out.write(dataBuffer.toString());
out.flush();
%>


需特别注意的是:

 

1. 一定要通过http url  的方式访问测试。放在tomcat 或是weblogic 中。

2. store 中要指定reader 的totalProperty。否则就只有一页了。


 

posted @ 2013-07-24 19:32  javawebsoa  Views(598)  Comments(0Edit  收藏  举报