在适配器中调用normalize

时间:2014-11-10 13:13:04

标签: ember.js

TL; DR:您在何处以及如何调用normalize方法,将服务器响应格式化为商店期望的内容?

我正在重写适配器来创建一个JSON RPC适配器,并且在规范化服务器的响应方面遇到一些麻烦 - 问题是我不知道在哪里调用Normalize,即:

createRecord: function(store, type, record){

    var data = {};
    var serializer = store.serializerFor(type.typeKey);
    serializer.serializeIntoHash(data, type, record, { includeId: true });

    var params = data[type.typeKey];

    return this.send('create', [params], null, type.typeKey, null, null, null);        

  }

发送的内容是创建ajax请求:

 send: function(method, args, kwargs, model, url, success, error){    

    var data = JSON.stringify(this.getData(model, method, args, kwargs, success, error));
    var settings = this.getSettings(data, success, error);        
    return $.ajax(this.get('host')+'/'+this.get('namespace'), settings);
  }

GetData将要发送到服务器的JSON格式化为

{" ID":1,"方法":"调用"" jsonrpc":" 2.0&#34 ;," PARAMS" {"模型":"使用者""方法":"创建"&# 34; ARGS":[{"用户名":" dsadfdasf"}]," kwargs" {"上下文":&# 34; elink"}}}

最后是getSettings:

getSettings: function(data, success, error){

    var settings = {};
    settings.type = 'POST';
    settings.data = data;

    settings.success = success || function(data){                        
      data[JSON.parse(settings.data).params.model] = data.result[0];  

      delete data.result;
      delete data.jsonrpc;
      delete data.id;


    };
    settings.error = error || function(xhr){
      cconsole.log('ERROR:' + xhr);
    };
    return settings;
  }

这里,getSettings.success执行自己的规范化,因为返回的对象始终采用以下格式:{"result":[{"username":"billyJoe","id":11}],"jsonrpc":"2.0","id":15223}

它的作用是删除jsonrpc和id属性,'重命名'将结果转换为请求的模型名称(进入用户),将其转换为对象而不是列表,最后得到:{"user":{"username":"billyJoe","id":11}}

这是商店对createRecord或find(model,id)的期望。但是,如果查询控制器期望列表中有多个用户的记录:

{"users":[{"username":"billyJoe","id":11}]}(注意' userS'和[])。 所以我需要一个规范化器来根据调用哪个函数来格式化数据。

最后一个问题:我究竟在哪里调用Normalize?我不能在getSettings中调用它,因为它没有对商店的引用(我应该通过调用更深入地传递对商店的引用吗?)

我会在createRecord中调用它,但它会返回一个promise,而不是我正在寻找的实际响应(我会以某种方式使用它来等待数据吗?)

我是否更进一步并覆盖model.save()和store.find()以规范化?

我知道问题看似愚蠢,所有这些都是可能的,但我正在寻找最合适的方式。

1 个答案:

答案 0 :(得分:1)

send方法中处理响应时会发生规范化。以下是在DS.RestAdapter(Source)中完成的操作:

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

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

      hash.success = function(json, textStatus, jqXHR) {
        json = adapter.ajaxSuccess(jqXHR, json);
        if (json instanceof InvalidError) {
          Ember.run(null, reject, json);
        } else {
          Ember.run(null, resolve, json);
        }
      };

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

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

ajax函数将是您在send方法中尝试执行的操作。

此函数构建了请求(hash对象),然后通过ajax发送。

当请求成功并且将传递响应数据时,将调用您的规范化函数(在上面的DS示例中,这发生在json = adapter.ajaxSuccess(jqXHR, json);调用。在规范化之后,您使用规范化数据解析promise这是通过Ember.run(null, resolve, json);电话完成的。