EmberJS中EmberData如何解析非默認格式的JSON數據

背景與問題

最近在使用EmberJS作爲前端MVC框架來編寫前端應用,但遇到了一個問題,EmberData要求的JSON格式默認爲下面這樣:前端

{
    "user":[
        {
            "name": "puras1",
            ......
        },
        {
            "name": "puras2",
            ......
        },
        {
            "name": "puras3",
            ......
        }
    ]
}

而咱們後端返回的格式卻與之不一樣,是下面這樣的格式:ajax

{    
    "errcode": 0,
    "message": "success",
    "ret": 0,
    "data": {
        "user":[
            {
                "name": "puras1",
                ......
            },
            {
                "name": "puras2",
                ......
            },
            {
                "name": "puras3",
                ......
            }
        ]
    }
}

經過DS.RESTAdapter來讀取數據的話,是沒法正常工做的。
想了三種辦法來解決這個問題。json

解決辦法

主要思路是重寫RESTAdapter中的ajax方法,Ajax方法以下:後端

ajax: function(url, type, hash) {
    var adapter = this;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      hash = adapter.ajaxOptions(url, type, hash);

      hash.success = function(json) {
        Ember.run(null, resolve, json);
      };

      hash.error = function(jqXHR, textStatus, errorThrown) {
        Ember.run(null, reject, adapter.ajaxError(jqXHR));
      };

      Ember.$.ajax(hash);
    }, "DS: RestAdapter#ajax " + type + " to " + url);
  }

方法中,若是請求成功,則會調用hash.success方法,直接把JSON串傳到了Ember.run方法中。因爲咱們後端返回的格式不一樣,咱們想傳JSON中指定的內容到Ember.run方法中。以下面解決方法中,根據傳回的JSON串結構,使用json.data來替代原來的json。框架

方法一:繼承RESTAdapter實現本身的Adapter

自定義一個Adapter,繼承RESTAdapter,重寫Ajax方法:this

App.MKRESTAdapter = DS.RESTAdapter.extend({
    ajax: function(url, type, hash) {
        var adapter = this;
        return new Ember.RSVP.Promise(function(resolve, reject) {
            hash = adapter.ajaxOptions(url, type, hash);

            hash.success = function(json) {
                Ember.run(null, resolve, json.data);
            };
            hash.error = function(jqXHR, textStatus, errorThrown) {
                Ember.run(null, reject, adapter.ajaxError(jqXHR));
            };

            Ember.$.ajax(hash);
        }, "DS: RESTAdapter#ajax " + type + " to " + url);
    }
});

在使用的時候,用MKRESTAdapter來替代RESTAdapter:url

//App.ApplicationAdapter = DS.RESTAdapter.extend();
// 修改爲
App.ApplicationAdapter = App.MKRESTAdapter.extend();

缺點:須要多加載一個自定義的類。code

方法二:經過reopen重寫RESTAdapter的Ajax方法

不從新自定義Adapter,直接經過reopen來重寫RESTAdapter:繼承

DS.RESTAdapter.reopen({
    ajax: function(url, type, hash) {
        var adapter = this;
        return new Ember.RSVP.Promise(function(resolve, reject) {
            hash = adapter.ajaxOptions(url, type, hash);

            hash.success = function(json) {
                Ember.run(null, resolve, json.data);
            };
            hash.error = function(jqXHR, textStatus, errorThrown) {
                Ember.run(null, reject, adapter.ajaxError(jqXHR));
            };

            Ember.$.ajax(hash);
        }, "DS: RESTAdapter#ajax " + type + " to " + url);
    }
});

使用方式不變。hash

缺點:改變了RESTAdapter默認的處理方式,並且是全局模式的,在其餘地方若是使用RESTAdapter可能會受到影響。

方法三:經過reopen重寫ApplicationAdapter的Ajax方法

從使用角度上來說,App.ApplicationAdapter也是繼承了RESTAdapter,只不過是EmberJS有個默認的實現而已,咱們可使用方法一中的方式,來重寫ajax方法:

App.ApplicationAdapter.reopen({    
    ajax: function(url, type, hash) {
        var adapter = this;
        return new Ember.RSVP.Promise(function(resolve, reject) {
            hash = adapter.ajaxOptions(url, type, hash);

            hash.success = function(json) {
                Ember.run(null, resolve, json.data);
            };
            hash.error = function(jqXHR, textStatus, errorThrown) {
                Ember.run(null, reject, adapter.ajaxError(jqXHR));
            };

            Ember.$.ajax(hash);
        }, "DS: RESTAdapter#ajax " + type + " to " + url);
    }
});

最後選擇的是方法三,又實現了需求,又沒有影響RESTAdapter默認的形爲。

以上!

相關文章
相關標籤/搜索