EmberJS中EmberData如何解析非默认格式的JSON数据

背景与问题

最近在使用EmberJS做为前端MVC框架来编写前端应用,但遇到了一个问题,EmberData要求的JSON格式默认为下面这样:

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

而我们后端返回的格式却与之不同,是下面这样的格式:

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

通过DS.RESTAdapter来读取数据的话,是无法正常工作的。
想了三种办法来解决这个问题。

解决办法

主要思路是重写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方法:

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:

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

缺点:需要多加载一个自定义的类。

方法二:通过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);
    }
});

使用方式不变。

缺点:改变了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默认的形为。

以上!

转载于:https://my.oschina.net/puras/blog/284690

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值