如何为 ember.js 创建自定义适配器?

IT技术 javascript ajax rest ember.js
2021-01-14 07:15:51

我打算使用 ember.js,但是我的 REST api 与打包的 REST Adapter 并不完全一致。我想“覆盖” find 并能够将我自己的 ajax 放入其中。我不喜欢 ember findAll 如何在没有分页选项的情况下检索我的所有文档,以便与其他查询参数一起使用 - 这就是我想编写自己的 ajax 的原因。我一直无法找到任何关于我将如何执行此操作的文档。

3个回答

对于 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) {
    // 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

序列化器

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

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

  1. 如果原始请求是针对单个记录(例如 find/save)或 extractArray,如果原始请求是针对记录数组(例如 findAll/findQuery),则将有效负载发送到 extractSingle
  2. 这些方法的默认行为是将有效负载的顶层拆分为多个较小的记录。
  3. 这些较小的记录中的每一个都被发送到归一化,它可以一次对一个记录进行归一化。
  4. 最后,可以对特定类型的记录进行特殊规范化。
    App.PostSerializer = DS.RESTSerializer.extend({
      提取单:功能(存储,类型,有效载荷,ID){
        // 按摩
        this._super(store, type, payload, id);
      },
      提取数组:函数(存储,类型,有效载荷){
        // 按摩
        this._super(store, type, payload);
      },
      规范化:函数(类型,哈希,属性){
        // 按摩
        this._super(type, hash, property);
      }
    });
  • 当有效负载的顶级组织与 Ember Data 预期的不同时,请使用 extractSingle 和 extractArray
  • 如果有效载荷中的所有子哈希都可以以相同的方式标准化,则使用 normalize 来标准化子哈希。
  • 使用 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 without Ember Data: Ember without Ember Data

你不需要 revision: 13
2021-03-16 07:15:51
太好了,那些都是Ember.Adapter中实现的方法吗?我找不到任何关于 ember 数据的信息。只是像基本适配器一样使用的方法,还是我会推出全新的方法?ember-data 的文档在哪里?
2021-03-25 07:15:51
这个答案已经过时了。Ember Data 在稳定发布的过程中经历了重大变化。
2021-03-29 07:15:51
谢谢,我实际上使用 ember 模型而不是 ember-data,所以我不熟悉商店等。
2021-04-04 07:15:51
它没有声称是最新版本的最新版本,它从一开始就说明了一个版本。而且稳定性方面,现在和年初一样稳定,主要是特色游戏,还有json api。
2021-04-09 07:15:51

我有同样的问题。我也想在我的后端 (cakePHP) 中使用稍微不同的格式,但不知道该怎么做。前面的答案很好,但您可能不需要重新定义每个方法,而只需通过覆盖 RESTAdapter 中的 buildURL 来更改 URL 的格式。

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

  • /users.json (findAll)
  • /users/view/1.json(查找)
  • /用户/删除/1.json
  • /users/edit.json (POST)
  • /users/add.json (POST)

经过大量的头发拉扯并意识到 ember-data 是必不可少的,我使用了以下代码:

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 数据。我希望他们有一个简单的例子,如何为不同的情况编写不同类型的适配器。

你是如何解决你的情况下的 HTTP 方法替换的?我的意思是“/users/edit.json (POST)”。默认的 ember HTTP 修改方法是 PUT。
2021-04-09 07:15:51

对于那些自己编码适配器的人,如果您需要从适配器返回一个值(例如,userId),您可以返回 json 或 promise。这是返回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 Promise的更多信息:https : //hackhands.com/3-ways-ember-js-leverages-promises/或在此处http://emberjs.com/api/classes/RSVP.Promise.html