Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks

          Ext.data專題一:Ext.data簡介

          Ext.data在命名空間中定義了一系列store、reader和proxy。

          Grid和ComboxBox都是以Ext.data為媒介獲取數(shù)據(jù)的,它包含異步加載、類型轉(zhuǎn)換、分頁等功能。

          Ext.data默認(rèn)支持Array、JSON、XML等數(shù)據(jù)格式,可以通過 Memory、HTTP、ScriptTag等方式獲得這些格式的數(shù)據(jù)。如果要實現(xiàn)新的協(xié)議和新的數(shù)據(jù)結(jié)構(gòu),只需要擴(kuò)展reader和proxy即可。 DWRProxy就實現(xiàn)了自身的proxy和reader,讓EXT可以直接從DWR獲得數(shù)據(jù)

          Ext.data專題二:Ext.data.Connection

          Ext.data.Connection 是對Ext.lib.Ajax的封裝,它提供了配置使用Ajax的通用方式,它在內(nèi)部通過Ext.lib.Ajax實現(xiàn)與后臺的異步調(diào)用。與底層的 Ext.lib.Ajax相比,Ext.data. Connection提供了更簡潔的配置方式,使用起來更方便。

          Ext.data.Connection 主要用于在Ext.data.HttpProxy和Ext.data.ScriptTagProxy中執(zhí)行與后臺交互的任務(wù),它會從指定的URL獲得數(shù) 據(jù),并把后臺返回的數(shù)據(jù)交給HttpProxy或ScriptTagProxy處理,Ext.data.Connection的使用方式如代碼清單


          var conn = new Ext.data.Connection({

              autoAbort: false,

              defaultHeaders: {

                  referer: 'http://localhost:8080/'

              },

              disableCaching : false,

              extraParams : {

                  name: 'name'

              },

              method : 'GET',

              timeout : 300,

              url : '01-01.txt'


          });

          在使用 Ext.data.Connection之前,都要像上面這樣創(chuàng)建一個新的Ext.Connection實例。我們可以在構(gòu)造方法里配置對應(yīng)的參數(shù),比如 autoAbort表示鏈接是否會自動斷開、default- Headers參數(shù)表示請求的默認(rèn)首部信息、disableCaching參數(shù)表示請求是否會禁用緩存、extraParams參數(shù)代表請求的額外參數(shù)、 method參數(shù)表示請求方法、timeout參數(shù)表示連接的超時時間、url參數(shù)表示請求訪問的網(wǎng)址等。

          在創(chuàng)建了conn之后,可以調(diào)用request()函數(shù)發(fā)送請求,處理返回的結(jié)果,如下面的代碼所示


          Ext.data專題三:Ext.data.Record

          Ext.data.Record就是一個設(shè)定了內(nèi)部數(shù)據(jù)類型的對象,它是Ext.data.Store的最基本組成部分。如果把Ext.data.Store看作是一張二維表,那么它的每一行就對應(yīng)一個Ext.data. Record實例。

          Ext.data.Record的主要功能是保存數(shù)據(jù),并且在內(nèi)部數(shù)據(jù)發(fā)生改變時記錄修改的狀態(tài),它還可以保留修改之前的原始值。

          我們使用Ext.data.Record時通常都是由create()函數(shù)開始,首先用create()函數(shù)創(chuàng)建一個自定義的Record類型,如下面的代碼所示。

          var PersonRecord = Ext.data.Record.create([

              {name: 'name', type: 'string'},

              {name: 'sex', type: 'int'}

          ]);

          PersonRecord就是我們定義的新類型,包含字符串類型的name和整數(shù)類型的sex兩個屬性,然后我們使用new關(guān)鍵字創(chuàng)建PersonRecord的實例,如下面的代碼所示。

          var boy = new PersonRecord({

              name: 'boy',

              sex: 0

          });

          創(chuàng)建對象時,可以直接通過構(gòu)造方法為對象賦予初始值,將'boy'賦值給name,0賦值給sex。

          現(xiàn)在,我們得到了PersonRecord的實例boy,如何才能得到它的屬性呢?以下三種方式都可以獲得boy中name屬性的數(shù)據(jù),如下面的代碼所示。

          alert(boy.data.name);

          alert(boy.data['name']);

          alert(boy.get('name'));

          這里涉及 Ext.data.Record的data屬性,這是定義在Ext.data.Record中的一個公共屬性,用于保存當(dāng)前record對象的所有數(shù)據(jù)。 它是一個JSON對象,可以直接從它里面獲得需要的數(shù)據(jù)??梢酝ㄟ^Ext.data.Record的get()函數(shù)方便地從data屬性中獲得指定的屬性 值。

          如果我們需要修改boy中的數(shù)據(jù),請不要使用以下方式直接操作data,如下面的代碼所示。

              boy.data.name = 'boy name';

              boy.data['name'] = 'boy name';

          而應(yīng)該使用set()函數(shù),如下面的代碼所示。

              boy.set('name', 'body name');

          set()函數(shù)會判斷屬性值是否發(fā)生了改變,如果改變了,就要將當(dāng)前對象的dirty屬性設(shè)置為true,并將修改之前的原始值放入modified對象中,供其他函數(shù)使用。如果直接操作data中的值,record就無法記錄屬性數(shù)據(jù)的修改情況。

          Record的屬性數(shù)據(jù)被修改后,我們可以執(zhí)行如下幾種操作。

          q   commit()(提交):這個函數(shù)的效果是設(shè)置dirty為false,并刪除modified中保存的原始數(shù)據(jù)。

          q   reject()(撤銷):這個函數(shù)的效果是將data中已經(jīng)修改了的屬性值都恢復(fù)成modified中保存的原始數(shù)據(jù),然后設(shè)置dirty為false,并刪除保存原始數(shù)據(jù)的modified對象。

          q   getChanges()獲得修改的部分:這個函數(shù)會把data中經(jīng)過修改的屬性和數(shù)據(jù)放在一個JSON對象里并返回。例如上例中,getChanges()返回的結(jié)果是{name:’body name’}。

          q   我們還可以調(diào)用isModified()判斷當(dāng)前record中的數(shù)據(jù)是否被修改。

                Ext.data.Record還提供了用于復(fù)制record實例的函數(shù)copy()。

          var copyBoy = boy.copy();

          這樣我們就得到了boy的一個副本,它里面包含了boy的data數(shù)據(jù),但copy()函數(shù)不會復(fù)制dirty和modified等額外的屬性值。


          Ext.data專題四:Ext.data.Store

          Ext.data.Store是EXT中用來進(jìn)行數(shù)據(jù)交換和數(shù)據(jù)交互的標(biāo)準(zhǔn)中間件,無論是Grid還是ComboBox,都是通過它實現(xiàn)數(shù)據(jù)讀取、類型轉(zhuǎn)換、排序分頁和搜索等操作的。

          Ext.data.Store中有一個Ext.data.Record數(shù)組,所有數(shù)據(jù)都存放在這些Ext.data. Record實例中,為后面的讀取和修改操作做準(zhǔn)備。

          一、Ext.data.Store基本應(yīng)用

          在使用之前,首先要創(chuàng)建一個Ext.data.Store的實例,如下面的代碼所示。

          var data = [

              ['boy', 0],

              ['girl', 1]

          ];

          var store = new Ext.data.Store({

              proxy: new Ext.data.MemoryProxy(data),

              reader: new Ext.data.ArrayReader({}, PersonRecord)

          });

          store.load();

          每個store最少需要兩個組件的支持,分別是proxy和reader,proxy用于從某個途徑讀取原始數(shù)據(jù),reader用于將原始數(shù)據(jù)轉(zhuǎn)換成Record實例。

          這里我們使用的是 Ext.data.MemoryProxy和Ext.data.ArrayReader,將data數(shù)組中的數(shù)據(jù)轉(zhuǎn)換成對應(yīng)的幾個 PersonRecord實例,然后放入store中。store創(chuàng)建完畢之后,執(zhí)行store.load()實現(xiàn)這個轉(zhuǎn)換過程。

          經(jīng)過轉(zhuǎn)換之后,store里的數(shù)據(jù)就可以提供給Grid或ComboBox使用了,這就是Ext.data. Store的最基本用法。

          二、Ext.data.Store對數(shù)據(jù)進(jìn)行排序

          Ext.data.Store提供了一系列屬性和函數(shù),利用它們對數(shù)據(jù)進(jìn)行排序操作。

          可以在創(chuàng)建Ext.data.Store時使用sortInfo參數(shù)指定排序的字段和排序方式,如下面的代碼所示。

          var store = new Ext.data.Store({

              proxy: new Ext.data.MemoryProxy(data),

              reader: new Ext.data.ArrayReader({}, PersonRecord),

              sortInfo: {field: 'name', direction: 'DESC'}

          });

          這樣,在store加載數(shù)據(jù)之后,就會自動根據(jù)name字段進(jìn)行降序排列。對store使用store.setDefaultSort('name','DESC');也會達(dá)到同樣效果。

          也可以在任何時候調(diào)用sort()函數(shù),比如store.sort('name', 'DESC');,對store中的數(shù)據(jù)進(jìn)行排序。

          如果我們希望獲得store的排序信息,可以調(diào)用getSortState()函數(shù),返回的是類似{field: "name", direction: " DESC"}的JSON對象。

          與排序相關(guān)的參數(shù)還有 remoteSort,這個參數(shù)是用來實現(xiàn)后臺排序功能的。當(dāng)設(shè)置為remoteSort:true時,store會在向后臺請求數(shù)據(jù)時自動加入sort 和dir兩個參數(shù),分別對應(yīng)排序的字段和排序的方式,由后臺獲取并處理這兩個參數(shù),在后臺對所需數(shù)據(jù)進(jìn)行排序操作。remoteSort:true也會導(dǎo) 致每次執(zhí)行sort()時都要去后臺重新加載數(shù)據(jù),而不能只對本地數(shù)據(jù)進(jìn)行排序。

          三、Ext.data.Store加載及顯示數(shù)據(jù)

          store創(chuàng)建好后,需要調(diào)用load()函數(shù)加載數(shù)據(jù),加載成功后才能對store中的數(shù)據(jù)進(jìn)行操作。load()調(diào)用的完整過程如下面的代碼所示。

          store.load({

              params: {start:0,limit:20},

              callback: function(records, options, success){

                  Ext.Msg.alert('info', '加載完畢');

              },

              scope: store,

              add: true

          });

            params是在store加載時發(fā)送的附加參數(shù)。

            callback是加載完畢時執(zhí)行的回調(diào)函數(shù),它包含3個參數(shù):records參數(shù)表示獲得的數(shù)據(jù),options表示執(zhí)行l(wèi)oad()時傳遞的參數(shù),success表示是否加載成功。

          Scope用來指定回調(diào)函數(shù)執(zhí)行時的作用域。

            Add為true時,load()得到的數(shù)據(jù)會添加在原來的store數(shù)據(jù)的末尾,否則會先清除之前的數(shù)據(jù),再將得到的數(shù)據(jù)添加到store中。

          一般來說,為了對store中的數(shù)據(jù)進(jìn)行初始化,load()函數(shù)只需要執(zhí)行一次。如果用params參數(shù)指定了需要使用的參數(shù),以后再次執(zhí)行reload()重新加載數(shù)據(jù)時,store會自動使用上次load()中包含的params參數(shù)內(nèi)容。

          如果有一些需要固定傳遞的參數(shù),也可以使用baseParams參數(shù)執(zhí)行,它是一個JSON對象,里面的數(shù)據(jù)會作為參數(shù)發(fā)送給后臺處理,如下面的代碼所示。

          store.baseParams.start = 0;

          store.baseParams.limit = 20;

          為store加載數(shù)據(jù)之后,有時不需要把所有數(shù)據(jù)都顯示出來,這時可以使用函數(shù)filter和filterBy對store中的數(shù)據(jù)進(jìn)行過濾,只顯示符合條件的部分,如下面的代碼所示。

          filter( String field, String/RegExp value, [Boolean anyMatch],
          [Boolean caseSensitive] ) : void

          filter()函數(shù)的用法與之前談到的find()相似,如下面的代碼所示。

          store.filter('name', 'boy');

          對應(yīng)的filterBy()與findBy()類似,也可以在自定義的函數(shù)中實現(xiàn)各種復(fù)雜判斷,如下面的代碼所示。

          store.filterBy(function(record) {

              return record.get('name') == 'girl' && record.get('sex') == 1;

          });

          如果想取消過濾并顯示所有數(shù)據(jù),那么可以調(diào)用clearFilter()函數(shù),如下面的代碼所示。

          store.clearFilter();

          如果想知道store上是否設(shè)置了過濾器,可以通過isFiltered()函數(shù)進(jìn)行判斷。

          四、Ext.data.Store其他功能

          除了上面提到的數(shù)據(jù)獲取、排序、更新、顯示等功能外,store還提供了其他一些功能函數(shù)。

          collect( String dataIndex, [Boolean allowNull], [Boolean bypassFilter] ) : Array

          collect函數(shù)獲得 指定的dataIndex對應(yīng)的那一列的數(shù)據(jù),當(dāng)allowNull參數(shù)為true時,返回的結(jié)果中可能會包含null、undefined或空字符串, 否則collect函數(shù)會自動將這些空數(shù)據(jù)過濾掉。當(dāng)bypassFilter參數(shù)為true時,collect的結(jié)果不會受查詢條件的影響,無論查詢條 件是什么都會忽略掉,返回的信息是所有的數(shù)據(jù),如下面的代碼所示。

          alert(store.collect('name'));

          這樣會獲得所有name列的值,示例中返回的是包含了'boy'和'girl'的數(shù)組。

          getTotalCount()用于在翻頁時獲得后臺傳遞過來的數(shù)據(jù)總數(shù)。如果沒有設(shè)置翻頁,get- TotalCount()的結(jié)果與getCount()相同,都是返回當(dāng)前的數(shù)據(jù)總數(shù),如下面的代碼所示。

          alert(store.getTotalCount());

          indexOf(Ext.data.Record record)和indexOfId(String id)函數(shù)根據(jù)record或record的id獲得record對應(yīng)的行號,如下面的代碼所示。

          alert(store.indexOf(store.getAt(1)));

          alert(store.indexOfId(1001));

          loadData(object data, [Boolean append])從本地JavaScript變量中讀取數(shù)據(jù),append為true時,將讀取的數(shù)據(jù)附加到原數(shù)據(jù)后,否則執(zhí)行整體更新,如下面的代碼所示。

          store.loadData(data, true);

          Sum(String property, Number start, Number end):Number用于計算某一個列從start到end的總和,如下面的代碼所示。

          alert(store.sum('sex'));

          Ext.data專題五:常用proxy之MemoryProxy

          MemoryProxy只能從JavaScript對象獲得數(shù)據(jù),可以直接把數(shù)組,或JSON和XML格式的數(shù)據(jù)交給它處理,如下面的代碼所示。

          var proxy = new Ext.data.MemoryProxy([
              ['id1','name1','descn1'],
              ['id2','name2','descn2']
          ]);

          HttpProxy使用HTTP協(xié)議,通過Ajax去后臺取數(shù)據(jù),構(gòu)造它時需要設(shè)置url:'xxx.jsp'參數(shù)。這里的url可以替換成任何一個合法的網(wǎng)址,這樣HttpProxy才知道去哪里獲取數(shù)據(jù),如下面的代碼所示。

          var proxy = new Ext.data.HttpProxy({url:'xxx.jsp'});               

          后臺需要返回EXT所需要的JSON格式的數(shù)據(jù),下面的內(nèi)容就是后臺使用JSP的一個范例,如下面的代碼所示。

          response.setContentType("application/x-json");

          Writer out = response.getWriter();

          out.print("[" +

                  "['id1','name1','descn1']" +

                  "['id2','name2','descn2']" +

              "]");               

          請注意,這里的HttpProxy不支持跨域,它只能從同一域中獲得數(shù)據(jù)。如果想跨域,請參考下面的ScriptTagProxy。

          常用proxy之ScriptTagProxy

          ScriptTagProxy的用法幾乎和HttpProxy一樣,如下面的代碼所示。

          var proxy = new Ext.data.ScriptTagProxy({url:'xxx.jsp'});               

          從這里也看不出來它是如何支持跨域的,我們還需要在后臺進(jìn)行相應(yīng)的處理,如下面的代碼所示。

          String cb = request.getParameter("callback");

          response.setContentType("text/javascript");

          Writer out = response.getWriter();

          out.write(cb + "(");

          out.print("[" +

                  "['id1','name1','descn1']" +

                  "['id2','name2','descn2']" +

              "]");

          out.write(");");

          其中的關(guān)鍵就在于從請求中獲 得的callback參數(shù),這個參數(shù)叫做回調(diào)函數(shù)。ScriptTag- Proxy會在當(dāng)前的HTML頁面里添加一個<script type="text/javascript"src="xxx.jsp"> </script>標(biāo)簽,然后把后臺返回的內(nèi)容添加到這個標(biāo)簽中,這樣就可以解決跨域訪問數(shù)據(jù)的問題。為了讓后臺返回的內(nèi)容可以在動態(tài)生成的 標(biāo)簽中運行,EXT會生成一個名為callback的回調(diào)函數(shù),并把回調(diào)函數(shù)的名稱傳遞給后臺,由后臺生成callback(data)形式的響應(yīng)內(nèi)容, 然后返回給前臺自動運行。

          雖然上述處理過程比較難理解,但是我們只需要了解ScriptTagProxy的用法就足夠了。如果還想進(jìn)一步了解ScriptTagProxy的運行過程,可以使用Firebug查看動態(tài)生成的HTML以及響應(yīng)的JSON內(nèi)容。

          最后我們來分析一下EXT的API文檔中提供的示例,這段后臺代碼會自動判斷請求的類型,返回支持ScriptTagProxy或HttpProxy的數(shù)據(jù),如代碼清單10-2所示。

          代碼清單 在后臺同時支持HttpProxy和ScriptTagProxy

          boolean scriptTag = false;

          String cb = request.getParameter("callback");

          if (cb != null) {

              scriptTag = true;

              response.setContentType("text/javascript");

          } else {

              response.setContentType("application/x-json");

          }

          Writer out = response.getWriter();

          if (scriptTag) {

              out.write(cb + "(");

          }

          out.print(dataBlock.toJsonString());

          if (scriptTag) {

              out.write(");");

          }               

          代碼中通過判斷請求中是否包含callback參數(shù)來決定返回何種數(shù)據(jù)類型。如果包含,就返回ScriptTagProxy需要的數(shù)據(jù);否則,就當(dāng)作HttpProxy處理。

          posted on 2009-11-17 14:57 seal 閱讀(787) 評論(0)  編輯  收藏 所屬分類: EXTJS
          主站蜘蛛池模板: 永春县| 琼中| 彩票| 大同市| 金沙县| 务川| 科尔| 衡水市| 微博| 德庆县| 茶陵县| 厦门市| 江口县| 北辰区| 九龙坡区| 祁东县| 额济纳旗| 镇康县| 东港市| 昌吉市| 巴林右旗| 马鞍山市| 德安县| 防城港市| 沙雅县| 满城县| 隆尧县| 尉犁县| 宜宾县| 大荔县| 九寨沟县| 紫金县| 年辖:市辖区| 亳州市| 顺义区| 永兴县| 抚顺市| 兴宁市| 滦南县| 舞钢市| 沭阳县|