咖啡伴侶

          呆在上海
          posts - 163, comments - 156, trackbacks - 0, articles - 2

          Ext服務器交互技術詳解(一)

          Posted on 2008-04-07 11:00 oathleo 閱讀(1584) 評論(1)  編輯  收藏 所屬分類: Web

            Ext是一個非常好的Ajax框架,其華麗的外觀表現確實令我們折服,然而一個應用始終離開不服務器端,因此在實現開發中我們需要對Ext與服務器端的交互技術有較為詳細的了解,在開發中才能游刃有余地應用。本文對Ext應用中與服務器交互的常用方法作具體的介紹,本文的內容大部份來源于《ExtJS實用開發指南》
            總體來說,Ext與服務器端的交互應用可以歸結為三種類型,包含表單FormPanel的處理(提交、加載)、控件交互及用戶發起的Ajax請求等三種。
          一、表單提交(submit)及加載(load)
            這里說的表單是指用Ext的FormPanel建立的表單,看下面的例子:

          Ext.onReady( function () {
          ??
          var ?f = new ?Ext.form.FormPanel( {
          ??renderTo:
          " hello " ,
          ??title:
          " 用戶信息錄入框 " ,
          ??height:
          200 ,
          ??width:
          300 ,
          ??labelWidth:
          60 ,
          ??labelAlign:
          " right " ,
          ??frame:
          true ,
          ??defaults:
          {xtype: " textfield " ,width: 180 } ,
          ??items:[
          ??
          {name: " username " ,fieldLabel: " 姓名 " } ,
          ??
          {name: " password " ,fieldLabel: " 密碼 " ,inputType: " password " } ,
          ??
          {name: " email " ,fieldLabel: " 電子郵件 " } ,
          ??
          {xtype: " textarea " ,name: " intro " ,fieldLabel: " 簡介 " }
          ??],
          ??buttons:[
          {text: " 提交 " } , {text: " 取消 " } ]??
          ?}
          )
          ?}
          );

          ?

          要提交該表單,則可以直接調用FormPanel下面form對象的submit方法即可,代碼如下:

          f.form.submit( {
          ?????url:
          " server.js " ,
          waitTitle:
          " 請稍候 " ,
          ?????waitMsg:
          " 正在提交表單數據,請稍候。。。。。。 "
          ?????}
          );


            調用submit方法后,默認情況下服務器端應用程序需要返回一個JSON數據對象,該對象包含兩個屬性,success的值是布爾值true或false,如果success的值為true,則表示服務器端處理成功,否則表示失敗;而errors的值是一個對象,對象中的每一個屬性表示錯誤的字段名稱,而屬性值為錯誤描述。
            比如,如果我們有服務器端驗證,下面的返回結果表示當表單提交處理出錯時給客戶端返回的數據。
          server.js文件中的內容如下:

          {
          ????success:?
          false ,
          ????errors:?
          {
          ????????username:?
          " 姓名不能為空 " ,
          ????????times:?
          " 遲到次數必須為數字! "
          ????}

          }


          結果如圖所示:


          ?
            當然,如果success屬性值改為true,則表示服務器端的處理成功,此時可以在success定義的回調函數中作相應的處理,比如下面的代碼表示在表單處理成功后,彈出提示信息,代碼如下:

          f.form.submit( {
          ?????waitTitle:
          " 請稍候 " ,
          ?????waitMsg:
          " 正在提交表單數據,請稍候。。。。。。 " ,
          ?????url:
          " ?server.js " ,
          ?????method:
          " POST " ,
          ?????success:
          function (action,form)
          ?????
          {
          ??????alert(
          " 提交成功! " );
          ?????}
          )

          ?
            另外一種表單動作是表單中數據的加載。要給表單中的字段設置值,可以通過調用字段的setValue方法,也可以直接在初始化字段的時候在配置參數中設置value屬性值,另外還有一種方法是通過Ajax的方式從服務器端加載表單中各個字段的值。這種方式也就是我們這里要介紹的表單數據加載。
            ExtJS的表單數據加載通過BasicForm的load方法來進行,表單數據加載動作由類Ext.form.Action.Load定義,執行數據加載動作會到服務器端加載數據,默認情況下服務器端需要返回一個包含success屬性及data屬性的JSON對象,內容大致如下:

          ?

          {
          ????success:?
          true ,
          ????data:?
          {
          ????????username:?
          " 冷雨 " ,
          ????????times:?
          1
          ????}

          }


          下面我們看一個使用到表單數據加載的簡單示例代碼:

          Ext.QuickTips.init();
          Ext.onReady(
          function () {?
          ?
          var ?f = new ?Ext.form.FormPanel( {
          ??renderTo:
          " hello " ,
          ??title:
          " 用戶信息錄入框 " ,
          ??height:
          130 ,
          ??width:
          320 ,
          ??labelWidth:
          60 ,
          ??labelAlign:
          " right " ,
          ??frame:
          true ,
          ??defaults:
          {width: 180 ,xtype: " textfield " } ,
          ??items:[
          {
          ???xtype:
          " textfield " ,
          ???name:
          " username " ,
          ???fieldLabel:
          " 姓名 "
          ???}
          ,
          ???
          {
          ???xtype:
          " textfield " ,
          ???name:
          " times " ,
          ???fieldLabel:
          " 登錄次數 "
          ???}

          ??],
          ??buttons:[
          {text: " 加載表單數據 " ,
          ????handler:s}
          ]???
          ?}
          );?
          ?
          function ?s()
          ?
          {
          ?f.form.load(
          {
          ?????waitTitle:
          " 請稍候 " ,
          ?????waitMsg:
          " 正在加載表單數據,請稍候。。。。。。 " ,
          ?????url:
          " data.js " ,
          ?????success:
          function (action,form)
          ?????
          {
          ??????alert(
          " 加載成功! " );
          ?????}
          ,
          ?????failure:
          function (action,form)
          ?????
          {
          ??????alert(
          " 數據加載失敗! " );
          ?????}

          ?????}
          );?
          ?}

          ?
          ?}
          );

          ?

          服務器data.js中的內容為:

          {
          ????success:?
          true ,
          ????data:?
          {
          ????????username:?
          " 冷雨 " ,
          ????????times:?
          100
          ????}

          }


          當點擊“加載表單數據”按鈕的時候,會執行f這個函數,f函數中直接調用f.form.load({})來加載表單中的數據,load方法中的參數與submit方法類似。執行上面的代碼,在從服務器端成功加載數據后,會自動把加載的數據設置到表單對應的各個字段中,然后還會執行success指定的回調函數,如圖9-23所示。
          ?


          圖 9-23 表單數據加載示例

          二、控件的交互
            一些需要從服務器加載數據的控件會自動與服務器交互,比如TreePanel下面的TreeLoader、GridPanel里面用到的Store等。這些控件其實都可以加載各種類型的數據,也就是理論上服務器可以返回任意數據給Ext客戶端,然后由Ext客戶端轉化成這些控件可以識別的數據。這些控件都提供了默認的數據解析器,能解析固定格式的數據供這些控件使用,在使用這些控件的時候,我們需要仔細看這些控件的API,看他們具體能處理什么樣格式的數據,這樣就可以在服務器端返回其默認的數據格式即可。
            下面,我們來看TreePanel,這是Ext中用來顯示樹結構的控件,該控件可以通過一個url來加載樹的節點信息,并支持異步樹節點加載方式。看下面使用TreePanel的代碼:

          var ?root = new ?Ext.tree.AsyncTreeNode( {
          ??id:
          " root " ,
          ??text:
          " 樹的根 " }
          );
          ?
          var ?tree = new ?Ext.tree.TreePanel( {
          ??renderTo:
          " hello " ,
          ??root:root,
          ??loader:?
          new ?Ext.tree.TreeLoader( {url: " treedata.js " } ),
          ??width:
          100
          ?}
          );


            在代碼中,treedate.js表示服務器的程序,Ext在渲染這棵樹,需要加載樹節點的時候會向服務器發起一個請求,通過這個請求的返回結果來加載樹的節點信息。默認情況下Ext要求服務器端返回的是一個包含樹節點信息的JSON數組,格式如下:
            [{節點對象1},{節點對象2}]
            比如treedata.js中可以包含下面的數據:

          [ {
          ????????id:?
          1 ,
          ????????text:?
          ' 子節點1 ' ,
          ????????leaf:?
          true
          ????}
          , {
          ????????id:?
          2 ,
          ????????text:?
          ' 兒子節點2 ' ,
          ????????children:?[
          {
          ????????????id:?
          3 ,
          ????????????text:?
          ' 孫子節點 ' ,
          ????????????leaf:?
          true
          ????????}
          ]
          ???}
          ]


          下面是樹的顯示結果:
          ?

            再比如GridPanel,用于顯示表格數據,GridPanel控件使用Store來存放表格中的數據,而Ext中的Store通過DataReader來解析數據,不同的DataReader可以解析不同的數據,因此在使用表格的時候,根據客戶端使用的DataReader不同,服務器端需要返回相應格式的數據。假如我們使用XmlReader,Store的定義如下:
          ?

          var ?store = new ??Ext.data.Store( {
          ??url:
          " hello.xml " ,??
          ??reader:
          new ?Ext.data.XmlReader( {
          ???record:
          " row " }
          ,
          ???[
          " id " , " name " , " organization " , " homepage " ])
          ??}
          );?

          使用該store的表格代碼如下:

          Ext.onReady( function () {?
          ?
          var ?store = new ??Ext.data.Store( {
          ??url:
          " hello.xml " ,??
          ??reader:
          new ?Ext.data.XmlReader( {
          ???record:
          " row " }
          ,
          ???[
          " id " , " name " , " organization " , " homepage " ])
          ??}
          );?
          ?
          var ?colM = new ?Ext.grid.ColumnModel([ {header: " 項目名稱 " ,dataIndex: " name " ,sortable: true } ,
          ?????
          {header: " 開發團隊 " ,dataIndex: " organization " ,sortable: true } ,
          ?????
          {header: " 網址 " ,dataIndex: " homepage " ?} ]);
          ?
          var ?grid? = ? new ?Ext.grid.GridPanel( {
          ??renderTo:
          " hello " ,
          ??title:
          " 中國Java開源產品及團隊 " ,
          ??height:
          200 ,
          ??width:
          600 ,?
          ??cm:colM,
          ??store:store,
          ??autoExpandColumn:
          2
          ?}
          );?
          ?store.load();?
          ?}
          );

          ?

          這里要求服務器端返回類似下面的xml數據:

          <? xml?version="1.0"?encoding="UTF-8" ?>
          < dataset >
          ?
          < row >
          ??
          < id > 1 </ id >
          ??
          < name > EasyJWeb </ name >
          ??
          < organization > EasyJF </ organization >
          ??
          < homepage > www.easyjf.com </ homepage >
          ?
          </ row >
          ?
          < row >
          ??
          < id > 2 </ id >
          ??
          < name > jfox </ name >
          ??
          < organization > huihoo </ organization >
          ??
          < homepage > www.huihoo.org </ homepage >
          ?
          </ row >
          ?
          < row >
          ??
          < id > 3 </ id >
          ??
          < name > jdon </ name >
          ??
          < organization > jdon </ organization >
          ??
          < homepage > www.jdon.com </ homepage >
          ?
          </ row >
          ?
          < row >
          ??
          < id > 4 </ id >
          ??
          < name > springside </ name >
          ??
          < organization > springside </ organization >
          ??
          < homepage > www.springside.org.cn </ homepage >
          ?
          </ row >
          </ dataset >


          三、?Ext.Ajax.request方法
            其實,不管是FormPanel的處理,還是控件的交互,他們在訪問服務器端的時候,90%都是通過使用Ext.Ajax.request方法來進行的,該方法可以用來向服務器端發送一個http請求,并可以在回調函數中處理返回的結果。往遠程服務器發送一個HTTP請求,發送Ajax調用的時候該方法的簽名如下:
          Ext.Ajax.rquest( [Object options] ) : Number

            服務器的響應是異步的,因此需要在回調函數中處理服務器端返回的數據。回調函數可以定義在request方法調用的參數options中。另外,在request方法中可以定義Ajax請求的一些其它屬性。參數options是一個對象,該對象包含了Ajax請求所需的各種參數及回調處理參數等。options中可以包含的各個屬性及含義如下所示:
            url?String?指定要請求的服務器端url,默認值為Ajax對象中配置的URL參數值。
            params?Object/String/Function?指定要傳遞的參數,可以是一個包含參數名稱及值的對象,也可以是name=xx&birthday=1978-1-1類似的url編碼字符串,或者是一個能返回上述兩種內容的函數。
            method?String?指定發送Ajax請求使用的method,可以是GET或POST方式。默認情況下,如果請求中沒有傳遞任何參數則使用GET,否則使用POST。
            callback?Function?指定Ajax請求的回調函數,該函數不管是調用成功或失敗,都會執行。傳遞給回調函數的參數有三個,第一個options表示執行request方法時的參數,第二個success表示請求是否成功,第三個參數response表示用來執行Ajax請求的XMLHttpRequest 對象。關于XMLHttpRequest可以通過http://www.w3.org/TR/XMLHttpRequest/查詢詳細的信息。
            success?Function?指定當Ajax請求執行成功后執行的回調函數,傳遞給回調函數兩個參數,第一個參數response表示執行Ajax請求的XMLHttpRequet對象,第二個參數表示執行request方法時的options對象。
            failure?Function?指定當請求出現錯誤時執行的回調函數,傳遞給回調函數兩個參數,第一個參數response表示執行Ajax請求的XMLHttpRequet對象,第二個參數表示執行request方法時的options對象。
            scope?Object?指定回調函數的作用域,默認為瀏覽器window。
            form?Object/String?指定要提交的表單id或表單數據對象。
            isUpload?Boolean?指定要提交的表單是否是文件上傳表單,默認情況下會自動檢查。
            headers?Object?指定請求的Header信息。
            xmlData?Object?指定用于發送給服務器的xml文檔,如果指定了該屬性則其它地方設置的參數將無效。
            jsonData?Object/String?指定需要發送給服務器端的JSON數據。如果指定了該屬性則其它的地方設置的要發送的參數值將無效。
            disableCaching?Boolean?是否禁止cache。

            比如,下面是一個向服務器foo.ejf這個應用程序發起一個Ajax請求的應用示例程序:

          function ?successFn(response,options) {
          alert(
          ' 請求成功了 ' );
          }

          function ?failureFn(response,options) {
          alert(
          ' 請求失敗了 ' );
          }


          Ext.Ajax.request(
          {
          ???url:?
          ' foo.ejf ' ,
          ???success:?successFn,
          ???failure:?failureFn,??
          ???params:?
          {?foo:? ' bar ' ?}
          }
          );

            這里的回調函數返回中返回的參數是一個XHR(即XmlHttpRequest)對象,我們可以通過該對象的responseText或responseXML等屬性來得到從服務器端返回的數據信息。在Ajax應用中,我們經常會讓服務器端返回JSON數據,由于JSON數據是字符串,因此在程序中需要先把他解析成javascript對象才可以使用,把JSON數據解析成javascript對象可以直接使用Ext.decode方法。
            假如服務器返回的是下面的JSON數據對象:
            {
          ???????  username: "冷雨",
          ???????  times: 1
            }
          ?則回調函數中應用這樣來使用該對象:

          function ?successFn(response,options) {
          var ?obj = ?Ext.decode(response.responseText)?;
          alert(obj.username);
          }

          ??? Ext.Ajax.request是Ext與服務器端交互的核心,因此需要在應用中靈活使用。在下一篇文章中,我會對Ext應用中的服務器程序作介紹。本文的文字、代碼及圖片等均來源于《ExtJS實用開發指南》,版權歸原作者所有,該指南當前在北京、深圳、成都、重慶、沈陽、杭州、上海等城市均已經可以直接到服務點購買,具體聯系方式:http://www.vifir.com/stations.html。)。

          Feedback

          # re: Ext服務器交互技術詳解(一)   回復  更多評論   

          2008-04-22 10:00 by 夕顏
          頂~~~ 就需要這樣的資料
          主站蜘蛛池模板: 灌南县| 永修县| 桂东县| 新野县| 巴马| 开远市| 敦煌市| 色达县| 雷波县| 遂平县| 图们市| 民权县| 阿克| 丰原市| 师宗县| 南昌市| 榆社县| 德兴市| 焉耆| 鄯善县| 永安市| 平昌县| 蓝田县| 安达市| 邛崃市| 白银市| 阿鲁科尔沁旗| 灵宝市| 华阴市| 垫江县| 全州县| 洪江市| 乐清市| 翁牛特旗| 海伦市| 开鲁县| 东乡族自治县| 黔东| 马关县| 安国市| 冷水江市|