前言
分頁功能的實現有兩種途徑:
一種是服務端分頁方式, 也就是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=4String 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。否則就只有一頁了。