如何为ember.js创建自定义适配器? [英] How do you create a custom adapter for ember.js?

查看:87
本文介绍了如何为ember.js创建自定义适配器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划使用ember.js,但是我的REST api与打包的REST适配器不完全一致。我想覆盖找到,并能够把自己的ajax放在它里面。我不喜欢ember findAll如何检索所有我的文档,没有分页的选项,所以与其他查询参数一起将是有用的 - 这就是为什么我要写我自己的ajax。

解决方案

对于Ember数据

,我无法找到任何有关如何执行此操作的文档。

这是Ember Data 1.0 beta 9的最新版本。



扩展其中一个Ember数据适配器。要使其站点宽:

  App.ApplicationAdapter = DS.RESTAdapter.extend(.... 

要使其具体型号:

  App.FooAdapter = DS.RESTAdapter.extend(... 

然后你将定义您总是可以选择调用 this._super 并恢复到基本实现,例如

  App.NotesAdapter = DS.RESTAdapter.extend({
find:function(store,type,id){
id =foo+ id ;
return this._super(store,type,id);
}
});

或者你可以完全覆盖实现:

  App.NotesAdapter = DS.RESTAdapter.extend {
find:function(store,type,id){
//在这里做你的东西
return this.ajax(this.buildURL(type.typeKey,id),'GET') ;
},

findAll:function(store,type,sinceToke n){
//你的东西在这里
var query;

if(sinceToken){
query = {since:sinceToken};
}

返回this.ajax(this.buildURL(type.typeKey),'GET',{data:query});
},

findQuery:function(store,type,query){
//你的东西在这里
return this.ajax(this.buildURL(type。 typeKey),'GET',{data:query});
},

findMany:function(store,type,ids,owner){
return this.ajax(this.buildURL(type.typeKey),'GET',{ data:{ids:ids}});
},
.....
});

要查看完整的api,您可以重写: http://emberjs.com/api/data/classes/DS.RESTAdapter.html



Serializer



通常更重要的是滚动自己的序列化器,以按摩数据以适应您的休息终点。以下是过渡文档 https://github.com/emberjs/中的一些有用信息data / blob / master / TRANSITION.md



简短版本是,一旦Ajax请求完成,生成的有效内容将通过以下钩子发送:


  1. 如果原始请求是针对单个记录(如find / save)或extractArray(如果原始请求)是一个记录数组(如findAll / findQuery)

  2. 这些方法的默认行为是将有效载荷的顶层分成多个较小的记录。

  3. 这些较小记录中的每一个都被发送到规范化,一次可以对记录进行归一化。

  4. 最后,特定类型的记录可以被特别标准化。 li>



 
App.PostSerializer = DS.RESTSerializer.extend({
extractSingle:function(store,type,payload,id){
//按钮
this._super(store,type,payload,id);
},
extractArray:function(store,type,payload){
// massage
this._super(store,type,payload);
},
normalize:function(type,hash,property){
//按钮
this._super(type,hash,property);
}
});




  • 使用extractSingle和extractArray,当您的有效负载的顶层与Ember Data期望的不同时,如果有效负载中的所有子哈希可以以相同的方式进行归一化,则使用no​​rmalize来归一化子哈希值。

  • 使用normalizeHash来对特定的子哈希进行归一化,

  • 确保调用super,如果您覆盖extractSingle,extractArray或规范化,以便链接的其余部分将被调用。



滚动自己的



  App.FooAdapter = Ember.Object.extend({
找到:function(id){
return $ .getJSON('http://www.foolandia.com/foooo/'+ id);
}
});

然后从您的路线,或在哪里

  App.FooRoute = Ember.Route.extend({
model:function(){
var adapter = App.FooAdapter.create();
return adapter.find(1);
}
});

现在我个人将注入适配器到路线上,以使我的生活更轻松:

  App.initializer({
name:fooAdapter,

initialize:function(container,应用程序){
application.register(my:manager,application.FooAdapter);
application.inject(controller,fooAdapter,my:manager);
应用程序.inject(route,fooAdapter,my:manager);
}
});

然后在路线上你可以懒惰,做:

  App.FooRoute = Ember.Route.extend({
model:function(){
return this.fooAdapter.find(1);
}
});

示例: http://emberjs.jsbin.com/OxIDiVU/676/edit



您可以在没有Ember数据:没有Ember数据的Ember数据


I'm planning on using ember.js, however my REST api doesn't exactly align with the packaged REST Adapter. I would like to "override" find and be able to put my own ajax in it. I dislike how an ember findAll retrieves all my documents with no options for pagination, so that along with other query parameters would be useful --which is why I want to write my own ajax. I've been unable to find any documentation on how I would go about doing this.

解决方案

For Ember Data

This is up to date as of Ember Data 1.0 beta 9.

Extend one of the Ember Data Adapters. To make it site wide:

App.ApplicationAdapter = DS.RESTAdapter.extend(....

To make it model specific:

App.FooAdapter = DS.RESTAdapter.extend(...

Then you will define the implementation you'd like to override. You always have the option to call this._super and revert to the base implementation. e.g.

App.NotesAdapter = DS.RESTAdapter.extend({
  find: function(store, type, id) {
    id = "foo" + id;
    return this._super(store, type, id);
  }
});

Or you can completely override the implementation:

App.NotesAdapter = DS.RESTAdapter.extend({
  find: function(store, type, id) {
    // Do your thing here
    return this.ajax(this.buildURL(type.typeKey, id), 'GET');
  },

  findAll: function(store, type, sinceToken) {
    // Do your thing here
    var query;

    if (sinceToken) {
      query = { since: sinceToken };
    }

    return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
  },

  findQuery: function(store, type, query) {
    // Do your thing here
    return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
  },

  findMany: function(store, type, ids, owner) {
    return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } });
  },
   .....
});

To see the complete api you can override see: http://emberjs.com/api/data/classes/DS.RESTAdapter.html

Serializer

Often more important will be rolling your own serializer for massaging the data to fit your rest endpoint. Here's some useful information from the transition document https://github.com/emberjs/data/blob/master/TRANSITION.md .

The short version is that once an Ajax request has completed, the resulting payload is sent through the following hooks:

  1. The payload is sent to extractSingle if the original request was for a single record (like find/save) or extractArray if the original request was for an Array of records (like findAll/findQuery)
  2. The default behavior of those methods is to pull apart the top-level of the payload into multiple smaller records.
  3. Each of those smaller records is sent to normalize, which can do normalization a record at a time.
  4. Finally, specific types of records can be specially normalized.

    App.PostSerializer = DS.RESTSerializer.extend({
      extractSingle: function(store, type, payload, id) {
        // massage
        this._super(store, type, payload, id);
      },
      extractArray: function(store, type, payload) {
        // massage
        this._super(store, type, payload);
      },
      normalize: function(type, hash, property) {
        // massage
        this._super(type, hash, property);
      }
    });

  • use extractSingle and extractArray when the top-level of your payload is organized differently than Ember Data expects
  • use normalize to normalize sub-hashes if all sub-hashes in the payload can be normalized in the same way.
  • use normalizeHash to normalize specific sub-hashes.
  • make sure to call super if you override extractSingle, extractArray or normalize so the rest of the chain will get called.

Rolling your own

App.FooAdapter = Ember.Object.extend({
  find: function(id){
    return $.getJSON('http://www.foolandia.com/foooo/' + id);
  }
});

Then from your route, or wherever

App.FooRoute = Ember.Route.extend({
  model: function(){
    var adapter = App.FooAdapter.create();
    return adapter.find(1);
  }
});

Now personally I'd inject the adapter onto the routes just to make my life easier:

App.initializer({
    name: "fooAdapter",

    initialize: function (container, application) {
        application.register("my:manager", application.FooAdapter);
        application.inject("controller", "fooAdapter", "my:manager");
        application.inject("route", "fooAdapter", "my:manager");
    }
});

Then on the route you could be lazier and do:

App.FooRoute = Ember.Route.extend({
  model: function(){
    return this.fooAdapter.find(1);
  }
});

Example: http://emberjs.jsbin.com/OxIDiVU/676/edit

You can read more about Ember without Ember Data: Ember without Ember Data

这篇关于如何为ember.js创建自定义适配器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆