天天看點

ExtJs學習筆記(22)-XTemplate + WCF 打造無重新整理資料分頁

ExtJs的Grid元件雖然不管從哪一方面來講,都稱得上是很好很強大,但是總會有一些應用場景并不需要這麼多功能,比如網站的留言清單,開發者隻想要一個簡單的<li>或<table>清單而已,這時候XTemplate就顯得很有用了。

本文将講解如何用XTemplate結合WCF與服務端互動,生成資料清單,同時加上無重新整理分頁功能(預設情況下ExtJs并沒有為XTemplate并沒有提供分頁功能)

1.先做一些準備工作,寫一個通用的類(改編自老張的PageData),用于WCF向ExtJs傳回分頁資料

2.DateTime序列化問題,因為.net序列化DateTime時,不管你怎麼努力,隻要是DateTime類型,最終隻能生成類似 "F_Date":"\/Date(1221023588109+0800)\/"這樣的字元串,ExtJs并不能正确識别!為此我們需要一個第三方的用于序列化DateTime的小工具Newtonsoft.Json.dll,它是專門用于将對象序列化成Json字元串。重要的是,用這個序列化後的DateTime字元串,ExtJs能夠識别(注:百度搜尋一下"Newtonsoft.Json"很容易就能找到N多下載下傳的,下載下傳後直接添加到項目引用裡即可)

3.編寫具體的實體類T_GuestBook,直接在資料庫裡建好,拖到dbml裡就可以了,主要代碼如下(注意要設定dbml的序列化屬性為"單向",否則vs不會自動為class以及成員加上序列化标簽):

為閱讀友善,去掉了一些自動生成的代碼

4.建一個WCF服務,并添加一個方法:

注意,這裡我們傳回的是string類型,并且是用JavaScriptConvert.SerializeObject處理後的JSON字元串,至于WebInvoke(ResponseFormat = WebMessageFormat.Json這裡為什麼要加Json傳回格式,原因很簡單,不指定Json格式,預設就是以xml傳回的,會無端在前後加上更多無用字元

5.ExtJs前端完整代碼:

這裡有幾個要點:

(1).datetime在xtemplate中的格式化寫法:{F_Date:date("Y-m-d H:i:s")}

(2).服務端傳回字元格式的處理:

因為JavaScriptConvert.SerializeObject(_PageData)這裡已經成功序列化了,但是wcf的服務在傳回時,必須要有一種格式,要麼xml,要麼json,是以我們指定了wcf以json格式傳回後,會對正常的結果再做一次序列化,最後的結果是使字元串前後都加上了雙引号,同時把原來正常的雙引号做了轉義處理,參考下面的:

正常的Json字元串:

{"RecordCount":6,"PageSize":3,"PageCount":2,"CurrentPageIndex":1,"Data":[{"F_ID":1,"F_IP":"192.23.37.41","F_Date":new Date(1221052494578),"F_Content":"這是第一條留言","F_Reply":""},{"F_ID":2,"F_IP":"192.168.0.1","F_Date":new Date(1221052494578),"F_Content":"這是第二條留言","F_Reply":""},{"F_ID":3,"F_IP":"192.168.0.2","F_Date":new Date(1221052494578),"F_Content":"這是第三條留言","F_Reply":""}]}

伺服器傳回的Json字元串:

"{\"RecordCount\":6,\"PageSize\":3,\"PageCount\":2,\"CurrentPageIndex\":1,\"Data\":[{\"F_ID\":1,\"F_IP\":\"192.23.37.41\",\"F_Date\":new Date(1221052494578),\"F_Content\":\"這是第一條留言\",\"F_Reply\":\"\"},{\"F_ID\":2,\"F_IP\":\"192.168.0.1\",\"F_Date\":new Date(1221052494578),\"F_Content\":\"這是第二條留言\",\"F_Reply\":\"\"},{\"F_ID\":3,\"F_IP\":\"192.168.0.2\",\"F_Date\":new Date(1221052494578),\"F_Content\":\"這是第三條留言\",\"F_Reply\":\"\"}]}"

是以我們要處理一下,關鍵代碼:

//轉換伺服器端傳回字元串的格式

                        var data = request.responseText;

                        data = data.substr(1);

                        data = data.substr(0, data.length - 1);

                        data = data.replace(/\\\"/g, '"');                       

                        data = Ext.util.JSON.decode(data)

(3).為使分頁按鈕有效,我們需要在成功傳回服務端資料後,為每個分頁連結以及按鈕加上onClick事件,即這一部分

//開始處理分頁按鈕/連結事件

                        var oBtnGo = Ext.get("btnGo");

                        var oGoPage = Ext.get("GoPage");

                        oBtnGo.on("click", function() {

                            loadData(iPageSize, oGoPage.dom.value);

                        });

                        var oBtnFirst = Ext.get("btnFirst"); //第一頁

                        oBtnFirst.on("click", function() { loadData(iPageSize, 1); })

                        var oBtnPre = Ext.get("btnPre"); //上一頁

                        oBtnPre.on("click", function() { loadData(iPageSize, iCurrentPageIndex - 1); })

                        var oBtnNext = Ext.get("btnNext"); //下一頁

                        oBtnNext.on("click", function() { loadData(iPageSize, iCurrentPageIndex + 1); })

                        var oBtnLast = Ext.get("btnLast"); //最後一頁

                        oBtnLast.on("click", function() { loadData(iPageSize, iPageCount); })

   另外這一段代碼的位置,也要留意一下,不能寫在其它地方:比如Ajax請求之後,因為當Ajax還未成功傳回資料/XTemplate未成功更新時,分頁按鈕以及連結還沒有加載到頁面中,這時如果用Ext.get()取對象,Js會報錯

   完成了,我們來看下一效果:

最後講一點題外話:

   做完這個後,我在想:單就這個示例而言,這跟直接用asp.net ajax的updatePannel有什麼差別,有什麼優勢呢?相信也有不少人跟我有一樣的疑問,後來我想了想,至少有二個好處:

   a.updatepannel預設會引起大量的資料回發,雖然頁面沒重新整理,但是用戶端跟服務端之間的傳輸資料量很大,而用ExtJs+Wcf,除了wcf傳回的字元串,就沒其它東西了,性能上會提高

   b.相對而言,ExtJs的Ajax請求方式,我覺得比aspx.net ajax的更容易操作.