ExtJS 4.2 教程-07:Ext.Direct


在上一節中,我們介紹了ExtJS 中的服務器段數據代理,在介紹到Direct 代理的時候,我們提到了Ext.Direct。這一節我們將重點介紹Ext.Direct的具體用法,並對上一節中Direct代理進行補充。

Ext.Direct 提供了一種使用Javascript 調用服務器端方法的機制,它與服務器端技術無關,因此可以在php、java、.net 等眾多平台中使用該技術。

我們本節中將以RemotingProvider 為例進行講解。對於RemotingProvider 的執行流程,大致上是:定義API,並將API添加到Ext.direct.Manager,然后我們將通過調用API來執行遠程請求。請求過程中,ExtJS 將創建一個Ajax 請求,將Remoting有關的數據發送到服務器的Remoter頁面,Remoter將對其進行分流,根據action(對應類名)、method(對應方法名)調用不同的方法,完成執行調用后,將封裝好的結果返回給客戶端。

API 和 Router

在使用Ext.Direct的時候,我們需要將后台的類、方法等封裝成API的形式,然后在Ext.direct.Manager 中進行注冊。

通常情況下,API 可以由程序根據配置項生成,所謂的生成,無非是根據配置項生成可執行的Javascript代碼,並以<script>標簽的形式引入到頁面中。我們今天將采用直接定義的方式來完成。代碼如下:

var userAPI = Ext.create('Ext.direct.RemotingProvider', {
    url: rootUrl + 'DirectAPI/Router',
    actions: {
        User: [
            {
                name: 'GetUserList',
                len: 0
            },
            {
                name: 'GetUser',
                params: ['name']
            }
        ]
    }
});

userAPI 提供了兩個操作,分別是GetUserList 和GetUser,他們都數據類 User。url 指向了DirectAPI/Router,此時我們需要在程序中添加DirectAPIController,然后在里面定義三個方法,代碼如下:

public class DirectAPIController : Controller
{
    public static List<User> UserList = null;

    static DirectAPIController()
    {
        if (UserList == null)
        {
            UserList = new List<User>();
            UserList.Add(new User() { name = "www.qeefee.com", age = 1 });
            UserList.Add(new User() { name = "QF", age = 26 });
        }
    }

    //
    // GET: /DirectAPI/
    [HttpPost]
    public JsonResult Router(FormCollection collection)
    {
        Stream input = Request.InputStream;
        input.Seek(0, SeekOrigin.Begin);

        byte[] buffer = new byte[input.Length];

        Request.InputStream.Read(buffer, 0, (int)input.Length);
        string inputString = Encoding.UTF8.GetString(buffer);
        dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(inputString);

        ExtResult result = new ExtResult();
        result.tid = json.tid;
        result.action = json.action;
        result.method = json.method;
        result.type = json.type;

        string method = json.method;
        switch (method)
        {
            case "GetUserList":
                {
                    result.result = GetUserList();
                }
                break;
            case "GetUser":
                {
                    string name = json.data.name;
                    result.result = GetUser(name);
                }
                break;
        }
        return Json(result);
    }

    public List<User> GetUserList()
    {
        return UserList;
    }

    public User GetUser(string name)
    {
        return UserList.Find(m => m.name == name);
    }

}

代碼有點長了不好意思!主要的代碼在Router方法中,在讀取數據的時候,我使用Request 無法獲取到,無奈之下只能讀取InputStream,有知道為什么不能讀取Request 的朋友還望告知。

在方法中先將客戶端傳遞的POST數據進行讀取,然后轉換為Json字符串。在轉換完成后根據method路由分配,將得到的結果傳遞給客戶端。

這里對返回的數據進行了封裝,ExtResult 類代碼如下:

public class ExtResult
{
    public string action { get; set; }
    public string method { get; set; }
    public int tid { get; set; }
    public string type { get; set; }
    public object result { get; set; }
}

客戶端調用

有了我們前面定義的API,我們可以方便的使用定義好的方法:

User.GetUserList(function (result, event, success, options) {
    var msg = [];
    Ext.Array.each(result, function (item) {
        msg.push(item.name + "  " + item.age);
    });
    Ext.MessageBox.alert('提示', msg.join('<br />'));
});

我們把之前定義的User 作為靜態類,GetUserList 是它的一個靜態方法,我們可以像C#一樣調用后台的方法。

除了直接調用之外,我們可以結合上節課中介紹的DirectProxy 來使用:

//創建Store
var store = Ext.create('Ext.data.Store', {
    model: 'Person',
    proxy: {
        type: 'direct',
        directFn: User.GetUserList,
        reader: {
            type: 'json'
        }
    }
});

//加載store
store.load({
    callback: function (records, operation, success) {
        var msg = [];
        store.each(function (item) {
            msg.push(item.get('name') + '   ' + item.get('age'));
        });
        Ext.MessageBox.alert('提示', msg.join('<br />'));
    }
});

參數傳遞

Ext.Direct 支持兩種參數傳遞形式:匿名參數和命名參數。

匿名參數是在Ext.Direct 推出以后就支持的,它不指定參數的名稱,只指定參數個數,在調用的時候將參數作為一個字符串數組傳遞給后台。例如,我們為User 新增一個方法 GetUserByName,它需要一個name參數,我們此處使用匿名參數的形式:

{
    name: 'GetUserByName',
    len: 1
}

在調用的時候,將參數寫在回調方法之前:

User.GetUserByName('QF', callback);

如果使用匿名參數,則有多少個參數就在callback之前寫多少個參數,最終這些參數會作為data的一部分傳遞給服務器。

image

命名參數則是Ext 4.2中新增的,它允許在定義的時候指定參數的名稱,然后在調用的時候使用JSON的格式傳遞參數,例如我們之前定義的GetUser 方法,它有一個name參數:

{
    name: 'GetUser',
    params: ['name']
}

在調用的時候,我們需要使用JSON格式的數據,指定參數名稱對應的值:

User.GetUser({ name: 'QF' }, callback);

此時傳遞給服務器的數據形式如下:

image

消息訂閱

Ext.Direct 為我們提供了方便的消息訂閱機制。如果我們要訂閱名稱為“message”的消息,可以使用下面的代碼完成:

Ext.direct.Manager.on('message', function (e) {
    Ext.MessageBox.alert('提示', e.result);
});

此時,如果服務器返回的數據,type為event,name為message,則會彈出提示。服務器返回的數據:

image

 

輪詢 - PollingProvider

Ext.Direct 還提供了輪詢的方式,它會在指定時間段重復對數據庫的請求操作。

var polling = Ext.create('Ext.direct.PollingProvider', {
    url: rootUrl + 'DirectAPI/GetMessage',
    type: 'polling',
    interval: 5000,
    listeners: {
        data: function (provider, e, eOpts) {
            Ext.MessageBox.alert('', e.data.msg);
        }
    },
    id: 'GetMessagePolling'
});
//啟動連接
polling.connect();

PollingProvider 會定時請求url,當得到服務器響應的數據后,觸發data事件。

polling.connect() 方法會啟動連接,如果要關閉連接,則使用polling.disconnect()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM