你如何为ember.js创build一个自定义的适配器?

我正在计划使用ember.js,但是我的REST API并不完全alignment打包的REST适配器。 我想“重写”find并能够把我自己的ajax在其中。 我不喜欢一个烬如何findAll检索我的所有文档没有分页的选项,以便与其他查询参数将是有用的 – 这就是为什么我要写我自己的ajax。 我一直无法find任何关于如何去做的文件。

对于Ember数据

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

扩展其中一个Ember数据适配器。 为了使网站广泛:

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

为了使其具体模型:

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

然后你将定义你想要覆盖的实现。 您始终可以select调用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) { // 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 } }); }, ..... }); 

要查看可以覆盖的完整api,请参阅: http : //emberjs.com/api/data/classes/DS.RESTAdapter.html

串行

通常更重要的是将滚动您自己的序列化程序来处理数据以适应您的rest端点。 以下是来自转换文档https://github.com/emberjs/data/blob/master/TRANSITION.md的一些有用信息。;

简短的版本是,一旦Ajax请求完成,所产生的有效载荷通过以下钩子被发送:

  1. 如果原始请求是针对单个logging(如find / save),则将有效负载发送到extractSingle;如果原始请求针对的是一组logging(如findAll / findQuery)
  2. 这些方法的默认行为是将有效负载的顶层分成多个较小的logging。
  3. 每个较小的logging被发送到正常化,一次可以logging正常化。
  4. 最后,可以对特定types的logging进行特别的标准化。
     App.PostSerializer = DS.RESTSerializer.extend({
       extractSingle:function(store,type,payload,id){
         //按摩
         this._super(store,type,payload,id);
       },
       extractArray:function(store,type,payload){
         //按摩
         this._super(store,type,payload);
       },
       normalize:function(type,hash,property){
         //按摩
         this._super(type,hash,property);
       }
     });
  • 当您的有效负载的顶层的组织方式与Ember数据期望的不同时,使用extractSingle和extractArray
  • 如果有效载荷中的所有子哈希都可以用相同的方式归一化,则使用no​​rmalize来规范化子哈希。
  • 使用normalizeHash来规范化特定的子哈希值。
  • 如果你重写extractSingle,extractArray或者normalize,那么一定要调用super,这样链的其余部分才会被调用。

滚动你自己的

 App.FooAdapter = Ember.Object.extend({ find: 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) { application.register("my:manager", application.FooAdapter); application.inject("controller", "fooAdapter", "my:manager"); application.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数据的Ember

我有同样的问题。 我也想用我的后端(cakePHP)稍微不同的格式,并不知道如何做到这一点。 以前的答案是很好的,但你可能不需要重新定义每一个方法,只需要通过在RESTAdapter中重写buildURL来改变URL的格式。

例如,我想使用cakePHP的扩展名,并希望我的url看起来像这样,应用程序范围广:

  • /users.json(findAll)
  • /users/view/1.json(查找)
  • /users/delete/1.json
  • /users/edit.json(POST)
  • /users/add.json(POST)

大量的头发拉动,并认识到,烬数据是必不可less的我用了下面的代码:

 App.ApplicationAdapter = DS.RESTAdapter.extend({ buildURL: function(type, id) { var url = '/' + this.pluralize(type.typeKey); if (id) { url += '/' + id; } url += '.json'; return url; } }); 

Ember的文档很好,但是大部分的例子都使用FIXTURE数据。 我希望他们有一个简单的例子来说明如何为不同的情况编写不同types的适配器。

对于自己编写适配器的用户,如果需要从适配器(例如userId)返回值,则可以返回json或promise。 这是返回诺言的例子:

 App.RequestAdapter = Ember.Object.extend({ newRequest: function (data) { return new Ember.RSVP.Promise(function (resolve, reject) { Ember.$.ajax({ type: 'POST', // method post url: '/Request/Create', //target url data: JSON.stringify(data), //the JSON.stringify converts data to JSON dataType: "json", contentType: "application/json; charset=utf-8", success: function (response) { resolve(response); }, error: function (reason) { reject(reason); } }); }); } }); //use this adapter in your controller var adapter = App.RequestAdapter.create(); adapter.newRequest(data).then(function (response) { //newRequest is method of our adapter console.log(response.userId); //specify response data }, function(error){ //handle error }); 

您可以在这里获得有关Ember承诺的更多信息: https : //hackhands.com/3-ways-ember-js-leverages-promises/或这里http://emberjs.com/api/classes/RSVP.Promise.html