2.1. 功能豐富,無人能出其右
無論是界面之美,還是功能之強(qiáng),ext的表格控件都高居榜首。
單選行,多選行,高亮顯示選中的行,推拽改變列寬度,按列排序,這些基本功能咱們就不提了。
自動(dòng)生成行號,支持checkbox全選,動(dòng)態(tài)選擇顯示哪些列,支持本地以及遠(yuǎn)程分頁,可以對單元格按照自己的想法進(jìn)行渲染,這些也算可以想到的功能。
再加上可編輯grid,添加新行,刪除一或多行,提示臟數(shù)據(jù),推拽改變grid大小,grid之間推拽一或多行,甚至可以在tree和grid之間進(jìn)行拖拽,啊,這些功能實(shí)在太神奇了。更令人驚嘆的是,這些功能竟然都在ext表格控件里實(shí)現(xiàn)了。
呵呵~不過ext也不是萬能的,與fins的ecside比較,ext不能鎖定列(土豆說1.x里支持鎖定列,但是2.0里沒有了,因?yàn)橛绊懶?率。),也沒有默認(rèn)的統(tǒng)計(jì)功能,也不支持excel,pdf等導(dǎo)出數(shù)據(jù)。另外fins說,通過測試ecside的效率明顯優(yōu)于ext呢。:)
2.2. 讓我們搞一個(gè)grid出來耍耍吧。
光說不練不是我們的傳統(tǒng),讓我們基于examples里的例子,來自己搞一個(gè)grid看看效果,同時(shí)也可以知道一個(gè)grid到底需要配置些什么東西。
-
首先我們知道表格肯定是二維的,橫著叫行,豎著叫列。跟設(shè)計(jì)數(shù)據(jù)庫,新建表一樣,我們要先設(shè)置這個(gè)表有幾列,每列叫啥名字,啥類型,咋顯示,這個(gè)表格的骨架也就出來了。
ext里,這個(gè)列的定義,叫做ColumnModel,簡稱cm的就是它,它作為整個(gè)表格的列模型,是要首先建立起來的。
這里我們建立一個(gè)三列的表格,第一列叫編號(code),第二列叫名稱(name),第三列叫描述(descn)。
var cm = new Ext.grid.ColumnModel([ {header:'編號',dataIndex:'id'}, {header:'名稱',dataIndex:'name'}, {header:'描述',dataIndex:'descn'} ]);
看到了吧?非常簡單的定義了三列,每列的header表示這列的名稱,dataIndex是跟后面的東西對應(yīng)的,咱們暫且不提?,F(xiàn)在只要知道有了三列就可以了。
-
有了表格的骨架,現(xiàn)在我們要向里邊添加數(shù)據(jù)了。這個(gè)數(shù)據(jù)當(dāng)然也是二維了,為了簡便,我們學(xué)習(xí)examples里的array-grid.js里的方式,把數(shù)據(jù)直接寫到j(luò)s里。
var data = [ ['1','name1','descn1'], ['2','name2','descn2'], ['3','name3','descn3'], ['4','name4','descn4'], ['5','name5','descn5'] ];
很顯然,我們這里定義了一個(gè)二維數(shù)據(jù), (什么?你不知道這是二維數(shù)組?快改行吧,這里不是你該待的地方。)
這個(gè)有五條記錄的二維數(shù)組,顯示到grid里就應(yīng)該是五行,每行三列,正好對應(yīng)這id,name,descn,在我們的腦子里應(yīng)該可以想像出grid顯示的結(jié)果了,為了讓想像變成顯示,我們還需要對原始數(shù)據(jù)做一下轉(zhuǎn)化。
-
因?yàn)樵蹅兿M鹓rid不只能支持array,還可以支持json,支持xml,甚至支持咱們自己定義的數(shù)據(jù)格式,ext為咱們提供了一個(gè)橋梁, Ext.data.Store,通過它我們可以把任何格式的數(shù)據(jù)轉(zhuǎn)化成grid可以使用的形式,這樣就不需要為每種數(shù)據(jù)格式寫一個(gè)grid的實(shí)現(xiàn)了?,F(xiàn)在 咱們就來看看這個(gè)Ext.data.Store是如何轉(zhuǎn)換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要對應(yīng)兩個(gè)部分:proxy和reader。proxy告訴我們從哪里獲得數(shù)據(jù),reader告訴我們?nèi)绾谓馕鲞@個(gè)數(shù)據(jù)。
現(xiàn)在我們用的是Ext.data.MemoryProxy,它是專門用來解析js變量的。你可以看到,我們直接把data作為參數(shù)傳遞進(jìn)去了。
Ext.data.ArrayReader專門用來解析數(shù)組,并且告訴我們它會(huì)按照定義的規(guī)范進(jìn)行解析,每行讀取三個(gè)數(shù)據(jù),第一個(gè)叫id,第二個(gè)叫 name,第三個(gè)descn。是不是有些眼熟,翻到前面cm定義的地方,哦,原來跟dataIndex是對應(yīng)的。這樣cm就知道哪列應(yīng)該顯示那條數(shù)據(jù)了。 唉,你要是能看明白這一點(diǎn),那你實(shí)在是太聰明了。
記得要執(zhí)行一次ds.load(),對數(shù)據(jù)進(jìn)行初始化。
有兄弟可能要問了,要是我第一列數(shù)據(jù)不是id而是name,第二列數(shù)據(jù)不是name而是id咋辦?嗯,嗯,這個(gè)使用就用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兩列的數(shù)據(jù)翻轉(zhuǎn)了。如此這般,無論數(shù)據(jù)排列順序如何,我們都可以使用mapping來控制對應(yīng)關(guān)系,唯一需要注意的是,索引是從0開始的,所以對應(yīng)第一列要寫成mapping:0,以此類推。
-
哈哈,萬事俱備只欠東風(fēng),表格的列模型定義好了,原始數(shù)據(jù)和數(shù)據(jù)的轉(zhuǎn)換都做好了,剩下的只需要裝配在一起,我們的grid就出來了。
var grid = new Ext.grid.Grid('grid', { ds: ds, cm: cm }); grid.render();
注意:上頭是ext-1.x的寫法,Ext.grid.Grid的第一個(gè)參數(shù)是渲染的id,對應(yīng)在html里應(yīng)該有一個(gè) <div id="grid"></div>的東西,這樣grid才知道要把自己畫到哪里。
創(chuàng)建完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,把這個(gè)目錄copy到ext-1.x的example目錄下,就可以直接打開觀看效果。
2.3. 上邊那個(gè)是1.x的,2.0稍微有些不同哦
首先,Ext.grid.Grid已經(jīng)不見了,咱們需要用Ext.grid.GridPanel。需要傳遞的參數(shù)也有少許區(qū)別。
var grid = new Ext.grid.GridPanel({ el: 'grid', ds: ds, cm: cm });
看到了嗎?負(fù)責(zé)指定渲染位置的id放到了{(lán)}里邊,對應(yīng)的名字是el。似乎ext2里對這些參數(shù)進(jìn)行了統(tǒng)一,比以前更整齊了。
因?yàn)槠渌胤蕉家粯?,我就不多說了,html例子在是lingo-sample/2.0目錄下的02-01.html。
從截圖上看,少了斑馬條,下邊多了一條線,應(yīng)該只是css有所不同吧。
默認(rèn)情況下,兩個(gè)版本的grid都可以拖拽列,也可以改變列的寬度。不知道怎么禁用這兩個(gè)功能呢。
最大的不同應(yīng)該是1.x里默認(rèn)支持的右鍵效果,在2.0里不見了。
按shift和ctrl多選行的功能倒是都有。區(qū)別是,全選后,1.x必須按住ctrl才能取消,直接單擊其中一個(gè)行,不會(huì)取消全選功能,而2.0里只需要任意點(diǎn)擊一行,就取消全選,只選中剛才點(diǎn)擊的那行。
哦,哦,那顏色不要也算是區(qū)別吧。
2.4. 按順序,咱們先要把常見功能講到,讓grid支持按列排序
其實(shí)很簡單,需要小小改動(dòng)一下列模型。
var cm = new Ext.grid.ColumnModel([ {header:'編號',dataIndex:'id',sortable:true}, {header:'名稱',dataIndex:'name'}, {header:'描述',dataIndex:'descn'} ]);
如果你英語還可以,或者懂得查字典的話(軟件翻譯也算),那么你就會(huì)知道,多出來的這個(gè)sortable屬性應(yīng)該是可以排序的意思?,F(xiàn)在咱們試一下改動(dòng)后的效果。
看到了沒有?編號的標(biāo)題上有個(gè)小小的箭頭,表格里的數(shù)據(jù)也是按照編號做的逆序排列,如此簡單,我們就實(shí)現(xiàn)了按列排序。
很有趣的是,2.0加上sortable以后,1.x那種右鍵功能也跑回來了,不過它用的不是右鍵,而是下拉菜單似的實(shí)現(xiàn)方式。
什么?你問為什么其他兩列無法排序?!嗯,好像是因?yàn)槟氵€沒有給另兩列添加sortable屬性。
怎么加?!按編號那樣加就行了。
還是不會(huì)?!-_-。
var cm = new Ext.grid.ColumnModel([ {header:'編號',dataIndex:'id',sortable:true}, {header:'名稱',dataIndex:'name',sortable:true}, {header:'描述',dataIndex:'descn',sortable:true} ]);
這樣所有列都可以排序了。什么?怎么取消排序?!-_-。
2.5. 讓單元格里顯示紅色的字,圖片,按鈕,你還能想到什么?
嘿,希望你跟我一樣,不愿意只能在grid里看到文字,至少不是單調(diào)的,毫無特色的文字。有些人就問了,如果我想改變一下單元格里顯示內(nèi)容,應(yīng)該怎么辦呢?
非常不幸的是,ext的作者,偉大的jack早已經(jīng)想到了,說真的,你沒想到的,他都想到了,不只想到了,他還做出來了。
唉,這就是區(qū)別啊。為啥你就不能動(dòng)手做些東西呢?就知道向別人要這要那,唉。
首先,我宣布,偶們的數(shù)據(jù)要擴(kuò)充啦,每個(gè)人要加上一個(gè)性別字段。
var data = [ ['1','male','name1','descn1'], ['2','female','name2','descn2'], ['3','male','name3','descn3'], ['4','female','name4','descn4'], ['5','male','name5','descn5'] ];
男女搭配,干活不累撒。而且現(xiàn)在中國就是男多女少,我就還沒對象呢。征婚中,單身女性加(QQ)771490531詳談。
你可以試試不改其他的部分,顯示的結(jié)果是不會(huì)改變的,因?yàn)樵紨?shù)據(jù)要經(jīng)過ds的處理才能被grid使用,那么下一步我們就開始修改ds,把性別加進(jìn)去。
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'},把數(shù)組的第二列映射為性別?,F(xiàn)在grid可以感覺到sex了,嘿嘿。
不過grid還顯示不了性別這列,因?yàn)樵蹅冞€沒改cm。
var cm = new Ext.grid.ColumnModel([ {header:'編號',dataIndex:'id'}, {header:'性別',dataIndex:'sex'}, {header:'名稱',dataIndex:'name'}, {header:'描述',dataIndex:'descn'} ]);
到現(xiàn)在其實(shí)都沒什么新東西,但是你不覺得光看平板字,很難分出哪個(gè)是GG哪個(gè)是MM嗎?聽說過紅男綠女沒?要是男的都加上紅色,女的都變成綠色,那不是清楚多了。就像下面一樣。
怎么樣?是不是效果大不同了。你不會(huì)認(rèn)為很難吧,嗯,確實(shí),如果你對html和css完全搞不明白的話,勸你還是先去學(xué)學(xué)吧,對自己有信心的往下看。
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'} ]);
別被嚇到,這么一大段其實(shí)就是判斷是男是女,然后配上顏色。你要是覺得亂,也可以這么做。
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'} ]);
實(shí)際上這個(gè)renderer屬性至關(guān)重要,它的值是一個(gè)function,哦,你說不知道js里function可以這么用?那么恭喜你,現(xiàn)在你知道了。
renderer會(huì)傳遞個(gè)參數(shù)進(jìn)去,咱們grid里看到的,是這個(gè)函數(shù)的返回值,怎么樣,神奇吧?
同志們,你們也應(yīng)該看到了,返回html就可以,是html啊,html里有的東西,你返回什么就顯示什么,顏色,鏈接,圖片,按鈕,只要你愿意,整個(gè)網(wǎng)頁都可以返回回去。還有什么做不到的?哦,你不會(huì)html,那沒轍,回去學(xué)吧。
咱們先來個(gè)圖片。
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' />"; } }
是不是太簡單了,下面咱們來玩點(diǎn)兒高級的。
function renderDescn(value, cellmeta, record, rowIndex, columnIndex, store) { var str = "<input type='button' value='查看詳細(xì)信息' onclick='alert(\"" + "這個(gè)單元格的值是:" + value + "\\n" + "這個(gè)單元格的配置是:{cellId:" + cellmeta.cellId + ",id:" + cellmeta.id + ",css:" + cellmeta.css + "}\\n" + "這個(gè)單元格對應(yīng)行的record是:" + record + ",一行的數(shù)據(jù)都在里邊\\n" + "這是第" + rowIndex + "行\(zhòng)\n" + "這是第" + columnIndex + "列\(zhòng)\n" + "這個(gè)表格對應(yīng)的Ext.data.Store在這里:" + store + ",隨便用吧。" + "\")'>"; return str; }
來看看我們可以在render里用到多少參數(shù):
-
value是當(dāng)前單元格的值
-
cellmeta里保存的是cellId單元格id,id不知道是干啥的,似乎是列號,css是這個(gè)單元格的css樣式。
-
record是這行的所有數(shù)據(jù),你想要什么,record.data["id"]這樣就獲得了。
-
rowIndex是行號,不是從頭往下數(shù)的意思,而是計(jì)算了分頁以后的結(jié)果。
-
columnIndex列號太簡單了。
-
store,這個(gè)厲害,實(shí)際上這個(gè)是你構(gòu)造表格時(shí)候傳遞的ds,也就是說表格里所有的數(shù)據(jù),你都可以隨便調(diào)用,唉,太厲害了。
有個(gè)同學(xué)就問啦:EXT render的參數(shù),是如何得到的呢。因?yàn)槟阒v的那些都是EXT自己內(nèi)部的。它是如何把這些參數(shù)傳遞給render的呢?
這個(gè)問題其實(shí)比較簡單,只是你們想復(fù)雜了。既然是函數(shù),就肯定有調(diào)用它的地方,你找到GridView.js在里邊搜索一下renderer,就會(huì)看到調(diào)用render的地方,這些參數(shù)都是在這里傳進(jìn)去的。
好,看看效果吧。
剩下的,就是發(fā)揮各位聰明才智的時(shí)候了,舞臺(tái)已經(jīng)搭好,看你如何表演了。
html例子,1.x版本在lingo-sample/1.1.1目錄下的02-02.html,2.0的版本在lingo-sample/2.0目錄下的02-02.html。
2.6. 更進(jìn)一步,自動(dòng)行號和多選checkbox
實(shí)際上行號和多選checkbox都是renderer的延伸,當(dāng)然多選checkbox更酷一點(diǎn)兒,兩者經(jīng)常一起使用,所以讓我們放在一起討論好了。
只需要在cm中加上一行,這一行不會(huì)與ds中的任何數(shù)據(jù)對應(yīng),這也告訴我們可以憑空制作列,哈哈。
在之前的例子上改啦。
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,而是直接根據(jù)renderer返回rowIndex + 1,因?yàn)樗菑?開始的,所以加個(gè)一。截圖如下。
1.x的例子在lingo-sample/1.1.1/02-03.html
很遺憾的是,2.0里有自己的默認(rèn)實(shí)現(xiàn)了,咱們不能展現(xiàn)自己的手工技藝了,還是乖乖使用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'} ]);
你絕對會(huì)同意我的意見,Jack's work is amazing.實(shí)在是太神奇了。看看截圖就知道。
2.0的例子在lingo-sample/2.0/02-03.html
2.6.2. 全選checkbox的時(shí)間了,請?jiān)试S我讓2.0先上場。
因?yàn)?.0里有checkboxSelectionModel,這樣完全可以證實(shí)用別人的輪子,比自己造輪子要方便。而且咱們造的輪子完全沒有jack圓。不信的話,看下面1.x里的實(shí)現(xiàn)。
我們一直在修改cm,這次我們也要對它動(dòng)刀了,不過SelectionModel既sm也要處理一下,這是為了改變單選和多選行的方式,以前這些可以靠shift或ctrl實(shí)現(xiàn),而現(xiàn)在這些都要與checkbox關(guān)聯(lián)上了。
啦啦啦,先看圖片,后看代碼。
先看看具體多了什么
var sm = new Ext.grid.CheckboxSelectionModel();
神奇的是這個(gè)sm身兼兩職,使用的時(shí)候既要放到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時(shí)代的全選checkbox。
理論上只需要給cm再加一列,像自動(dòng)編號那樣,不對應(yīng)數(shù)據(jù),只顯示checkbox就可以了。難點(diǎn)就是checkbox與某一行被選擇的時(shí)候要對應(yīng)上,用checkbox選擇上,sm里也要讓這一行被選中,反之亦然。嗯,估計(jì)會(huì)比較復(fù)雜呢。
先放上顯示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上已經(jīng)有擴(kuò)展了,或者你可以看看我們弄下來的。 看看1.x多選樹的截圖。
2.7. 分頁了嗎?分頁了嗎?如果還沒分就看這里吧。
如果你有一千條信息,一次都輸出到grid里,然后讓客戶用下拉條一點(diǎn)兒一點(diǎn)兒去找吧。我們這里可是要做一個(gè)分頁效果了,不用滾動(dòng)屏幕,或者滾動(dòng)一下就可以看到本頁顯示的數(shù)據(jù),如果想看其他的只需要翻頁就可以了。同志們,加強(qiáng)客戶體驗(yàn)呀。
實(shí)際上,grid控件挺耗性能的,據(jù)土豆講一個(gè)頁面上放3個(gè)grid就可以感覺到響應(yīng)變慢,以前看過介紹,grid里顯示數(shù)據(jù)過多,聽說是上千條,也會(huì)明顯變慢。
所以說分頁是必不可少滴,而且jack提供了方便集成分頁工具條的方式,不用一下實(shí)在是太浪費(fèi)了。
兩步走,讓grid集成分頁。
從圖片可以清晰的看到,在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就設(shè)計(jì)的這么好,腳底下專門留了地方讓你放東西。我們老實(shí)不客氣,把Ext.PagingToolbar放到上邊,就可以顯示分頁工具條了。
這分頁工具條可不是個(gè)擺設(shè),你按了前一頁,后一頁,整個(gè)grid都要有反應(yīng)才對,要不咱們費(fèi)勁弄這個(gè)么東西過來干嘛呀?所以,我們在構(gòu)造 PagingToolbar的時(shí)候,不但告訴它,在gridFoot上顯示,還告訴它,進(jìn)行分頁跳轉(zhuǎn)的時(shí)候,要對ds也進(jìn)行操作。這個(gè)ds就是grid用 來獲取和顯示數(shù)據(jù)的,它一變整個(gè)grid都發(fā)生變化,嘿嘿~這就算共享數(shù)據(jù)模型了。厲害呀。
知道了分頁的玄機(jī),讓我們?nèi)嗳嘌劬?,好好看看里邊的參?shù)。
-
pageSize,是每頁顯示幾條數(shù)據(jù)。
-
displayInfo,跟下面的配置有關(guān),如果是false就不會(huì)顯示提示信息。
-
displayMsg,只有在displayInfo:true的時(shí)候才有效,用來顯示有數(shù)據(jù)的時(shí)候的提示信息,中國人應(yīng)該看得懂漢語,到時(shí)候{0},{1},{2}會(huì)自動(dòng)變成對應(yīng)的數(shù)據(jù),咱們只需要想辦法把話說通就行了。
-
emptyMsg,要是沒數(shù)據(jù)就顯示這個(gè),jack實(shí)在太貼心了,連這些小處都考慮得如此精細(xì)。
最好要注意的是,這段代碼必須放在grid.render()之后,估計(jì)是因?yàn)閯?dòng)態(tài)生成grid的dom后,才能獲得對應(yīng)的footPanel。
現(xiàn)在給出例子,1.x的例子在lingo-sample/1.1.1/02-05.html。
其實(shí),在下,一直,對于:必須先渲染grid才能獲得footPanel這事非常憤恨,你想啊,本來分頁也應(yīng)該屬于初始化的一部分,現(xiàn)在卻要先初始化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();
嘿嘿,加一個(gè)bbar的參數(shù)就可以了,bbar就是bottom bar啦,底端工具條。
不過還是要注意一點(diǎn),與1.x中不同的是,如果配置了分頁工具條,ds.load()就必須在構(gòu)造grid以后才能執(zhí)行,否則分頁工具條會(huì)不起作用??磥矸猪摴ぞ邨l會(huì)把自己和ds做一些關(guān)聯(lián),來完成與grid共享數(shù)據(jù)模型的。
對了,還有一點(diǎn)不同,1.x中分頁條不會(huì)隨著瀏覽器的大小改變,自動(dòng)放縮,這點(diǎn)在2.0中也解決了。
2.0的例子在lingo-sample/2.0/02-05.html。
2.7.3. 迫不得已,要加上后臺(tái)腳本了。
grid會(huì)每次都顯示ds中所有的數(shù)據(jù),咱們沒法利用靜態(tài)數(shù)據(jù)好好演示分頁,于是,必須寫后臺(tái)腳本,讓ext與后臺(tái)進(jìn)行數(shù)據(jù)交互才能看到真實(shí)的分頁效果。
咱們盡量在原來的基礎(chǔ)上修改啊,把注意力集中在關(guān)鍵部位,一次性突破。
我不會(huì)其他語言,后臺(tái)就用jsp寫啦。有個(gè)好消息是只要返回的數(shù)據(jù)格式一樣,ext才不管后臺(tái)是什么寫的呢。也就是這樣,不管你以后用什么實(shí)現(xiàn)后臺(tái),前臺(tái)的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代碼:
-
在進(jìn)行操作之前,我們先要獲得ext傳遞過來的兩個(gè)參數(shù):start和limit,start指的從第幾個(gè)數(shù)據(jù)開始顯示,limit是說從start開始,一共要用多少個(gè)數(shù)據(jù),當(dāng)然返回的數(shù)據(jù)可能會(huì)小于這個(gè)值。
-
咱們在后臺(tái)模擬對100條數(shù)據(jù)進(jìn)行分頁,在獲得了start和limit之后再生成json格式的數(shù)據(jù)。
何謂json?在理論講解之前先看看實(shí)例,讓我們能有個(gè)感性認(rèn)識,至于以后能不能升華到理性認(rèn)識,就看各位的悟性了。
模擬ext訪問后臺(tái),并傳遞兩個(gè)參數(shù)start=0&limit=10,把獲得的數(shù)據(jù)稍微整理一下,是這個(gè)樣子。
{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'} ]}
請記住這個(gè)數(shù)據(jù)格式,不管后臺(tái)是什么,只要滿足了這樣的格式要求,ext就可以接收處理,顯示到grid中。
我這里就不好好介紹json,現(xiàn)在只需要知道json里頭除了name(名稱)就是value(值),值有好幾種格式,如果是數(shù)字就不用加引號,如果加了引號就是字符串,如果用[]包裹就是數(shù)組,如果出現(xiàn){}就說明是嵌套的json。諸如此類。
簡單瞄了json一眼,開頭就是totalProperty:100,這告訴ext:“俺這里有100個(gè)數(shù)據(jù)呢。”,然后就是root:[], root對應(yīng)著一個(gè)數(shù)組,數(shù)組里有10個(gè)對象,每個(gè)對象都有id呀,name呀,descn呀。這10個(gè)數(shù)據(jù)最后就應(yīng)該顯示到表格里。
-
jsp里用for循環(huán)生成root數(shù)組里的數(shù)據(jù),這樣我們翻頁的時(shí)候可以看到數(shù)據(jù)的變化,要不每次都是一樣的數(shù)據(jù),你怎么知道翻頁是不是起作用了呢?
最后我們把得到的json字符串輸出到response里,ext也就可以獲得這些數(shù)據(jù)了。
結(jié)果經(jīng)過了一番折騰,我們的jsp已經(jīng)確定可以返回我們所需要的數(shù)據(jù)了。現(xiàn)在我們可以忘掉后臺(tái)是用什么語言寫的了,直接切入ext代碼,看看它是怎么樣才能跑去后臺(tái)獲得這些數(shù)據(jù)呢?
因?yàn)橐肓薺son作為數(shù)據(jù)傳輸格式,這次我們要對ext代碼進(jìn)行一次大換血了,請做好思想準(zhǔn)備。
-
換掉proxy,別在內(nèi)存里找了,讓我們通過http獲得我們想要的。
proxy: new Ext.data.HttpProxy({url:'grid.jsp'}),
創(chuàng)建HttpProxy的同時(shí),用url這個(gè)參數(shù)指定咱們?nèi)ツ睦锶?shù)據(jù),我們這里設(shè)置成grid.jsp,就是我們剛才討論的jsp腳本啦。
-
已經(jīng)不是數(shù)組了,現(xiàn)在要用json咯。
reader: new Ext.data.JsonReader({ totalProperty: 'totalProperty', root: 'root' }, [ {name: 'id'}, {name: 'name'}, {name: 'descn'} ])
看比ArrayReader多了什么?totalProperty對應(yīng)咱們jsp返回的totalProperty,也就是數(shù)據(jù)的總數(shù)。root對應(yīng)咱們jsp返回的root,就是一個(gè)包含返回?cái)?shù)據(jù)的數(shù)組。
-
好了,最后在初始化的時(shí)候,告訴我們希望獲得哪部分的數(shù)據(jù)就可以了。
ds.load({params:{start:0,limit:10}});
就在ds讀取的時(shí)候添加兩個(gè)參數(shù),start和limit,告訴后臺(tái),我們從第一個(gè)數(shù)可以取起,最多要10個(gè)。
在這里有一個(gè)小插曲,如果你按照我們以前的設(shè)置,grid是無法正常顯示的,因?yàn)閐s.load()無法在grid.render()前準(zhǔn)備好所有 數(shù)組,所以它不知道自己應(yīng)該實(shí)現(xiàn)多高。沒法子,我們只好為它指定一個(gè)固定的高度了。像這樣<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. 其實(shí)分頁不一定要踩在腳下,也可以頂在頭上。
我的意思是,grid除了FootPanel以外,還有HeaderPanel,意思就是頭頂上的面板。我們把分頁條放在上面也不會(huì)有任何問題。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就更簡單了,只需要改一個(gè)字母,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: "沒有記錄" }) });
|