DataProvider

2024-03-07 18:26 更新

DataProvider用于從Server端轉(zhuǎn)載數(shù)據(jù)到瀏覽器中,包含異步和同步兩種執(zhí)行模式。

Pure Client

在Pure Client的開發(fā)模式中,我們主要需要關(guān)注的是Dorado.AjaxDataProvider這個(gè)類。該類內(nèi)部通過Dorado的Ajax引擎向服務(wù)端請求數(shù)據(jù),返回的數(shù)據(jù)格式默認(rèn)應(yīng)為JSON形式。 下面的命令定義了一個(gè)DataSet,同時(shí)設(shè)置該DataSet通過AjaxDataProvider來提取數(shù)據(jù),數(shù)據(jù)事實(shí)上被保存在服務(wù)端data/phones.js文件中。

var dataSet = new Dorado.widget.DataSet({
    dataProvider: new Dorado.AjaxDataProvider("data/phones.js"),
    dataType: "Phone"
});

Dorado.AjaxDataProvider在發(fā)送Ajax請求時(shí)往往還會在請求中附帶一些其他的信息,這取決與相應(yīng)DataSet和DataType的設(shè)置。 例如我們?yōu)镈ataSet的parameter屬性定義了內(nèi)容,或者我們聲明了DataSet按照分頁的方式裝載數(shù)據(jù)。那么這些額外的參數(shù)和分頁的信息都會附帶在請求中被一同發(fā)送到服務(wù)器端。目前AjaxDataProvider所支持的額外信息包括:

  • parameter - 一組額外的屬性。一般是通過DataSet的parameter屬性定義的。
  • pageSize - 數(shù)據(jù)分頁裝載時(shí)每頁的記錄數(shù)。如果不支持?jǐn)?shù)據(jù)分頁裝載,此參數(shù)將是0。
  • pageNo - 數(shù)據(jù)分頁裝載時(shí)當(dāng)前請求的頁號。

Dorado.AjaxDataProvider默認(rèn)以POST方式發(fā)起請求,同時(shí)將上述的這些額外信息放置在POST請求的content中。這樣,我們在服務(wù)器端必須擁有一些相應(yīng)的支持才能讀到這些JSON信息。以Java為例,下面給出了一個(gè)可以解析并得到這些JSON信息的Servlet的實(shí)例。

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;

 
public class ExampleServiceServlet extends HttpServlet {
    private static final String JAVASCRIPT_TOKEN = "javascript";
    private static final int BUFFER_SIZE = 4096;

 
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        ServletInputStream in = request.getInputStream();
        try {
            String contentType = request.getContentType();
            if (contentType.contains(JAVASCRIPT_TOKEN)) {   // 判斷contentType以確認(rèn)客戶端是否是以JSON的信息發(fā)送POST信息
                StringBuffer buf = new StringBuffer();
                byte[] b = new byte[BUFFER_SIZE];
                for (int n; (n = in.read(b)) != -1;) {
                    buf.append(new String(b, 0, n));
                }
                JSONObject json = JSONObject.fromObject(buf.toString());    // 利用JSONObject工具類解析并得到了客戶端發(fā)送的JSON信息
                // 此處就可以利用這些JSON信息編寫自己的業(yè)務(wù)邏輯了
            }
        }
        finally {
            in.close();
        }
    }
}

當(dāng)然,在有些情況下我們可以希望自己來定義這些額外的信息應(yīng)該如何被傳遞到Server。這時(shí)最好的辦法就是派生出一個(gè)新的DataProvider,并且復(fù)寫其中的getLoadOptions方法。 假設(shè)我們希望將parameter中的個(gè)參數(shù)以及pageSize、pageNo全部放到請求的URL參數(shù)中,那么我們可以這樣來定義派生類:

Dorado.MyDataProvider = $extend(Dorado.AjaxDataProvider, {
    getLoadOptions: function(arg) {
        /* 調(diào)用父類中的處理邏輯
         * 由于我們知道原先的邏輯將額外數(shù)據(jù)都放置在jsonData中。因此我們可以從返回的options的jsonData屬性中取得這些信息。 
         */
        var options = $invokeSuper.call(this, arguments);

 
        var jsonData = options.jsonData;
        var parameter = Dorado.Object.apply({}, jsonData.parameter);    // 將jsonData中定義的子屬性復(fù)制到parameter中
        parameter.pageSize = jsonData.pageSize; // 將pageSize設(shè)置到parameter中
        parameter.pageNo = jsonData.pageNo; // 將pageNo設(shè)置到parameter中
        options.parameter = parameter;
        delete options.jsonData;    // 清除原先的jsonData
        return options;
    }
});

非Pure Client模式

該模式是指和dorado服務(wù)端的代碼整合開發(fā)的場景。在這種場景下,后臺的Ajax請求是由dorado后端的攔截器攔截并轉(zhuǎn)發(fā)請求的。 在這種模式下我們可以在view設(shè)計(jì)器的model節(jié)點(diǎn)下看到多種類型的DataProvider: 其中最常用的是DirectDataProvider。 例如我們在Java后臺通過annotation技術(shù)定義了一個(gè)DataProvider:

@Component
public class SimpleCRUD {
    @Resource
    private ProductDao productDao;


    @DataProvider
    public Collection<Product> getAll() throws Exception {
        return productDao.getAll();
    }
    ...  

接下來就可以在model中添加一個(gè)DirectDataProvider,并設(shè)置其interceptor屬性: 這樣這個(gè)Provider就知道通過interceptor攔截器去獲取數(shù)據(jù)。 該處使用的是spring:的表達(dá)式,表示要從后臺的spring服務(wù)中獲取beanId為simpleCRUD的對象中通過getAll方法獲取數(shù)據(jù)。 設(shè)置好之后我們再設(shè)置DataSet的dataProvider為這個(gè)自定義的dataProvider即完成了DataProvider的定義和使用。 當(dāng)然在日常使用中,可以再度簡化這個(gè)開發(fā)過程,在view中我們可以不用添加DirectDataProvider對象。而是直接在DataSet的dataProvider對象上定義: 這種方式會在dorado的內(nèi)部自動創(chuàng)建DirectDataProvider對象,這種使用方式更為簡潔一些。 當(dāng)然你在dorado的sample-center中還能看到這種定義方式: 看,這個(gè)地方連spring的id都可以省略。這是基于約定由于配置的一種使用方式,即假設(shè)當(dāng)前View的名稱和對應(yīng)Spring的id的名稱一樣的情況下,例如本例view的名稱為SimpleCRUD.view.xml,而對應(yīng)的服務(wù)bean的名稱為"simpleCURD",這種情況下我們就可以直接省略dataProvider屬性配置中beanId的編寫,直接寫#+對應(yīng)的方法名就可以。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號