32

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

4

3 回答 3

62

对于 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),则有效负载将发送到 extractSingle;如果原始请求针对记录数组(例如 findAll/findQuery),则将有效负载发送到 extractArray
  2. 这些方法的默认行为是将有效负载的顶层拆分为多个较小的记录。
  3. 这些较小的记录中的每一个都被发送到规范化,它可以一次对一条记录进行规范化。
  4. 最后,可以对特定类型的记录进行特殊规范化。
    App.PostSerializer = DS.RESTSerializer.extend({
      extractSingle:函数(存储,类型,有效负载,ID){
        // 按摩
        this._super(store, type, payload, id);
      },
      extractArray:函数(存储,类型,有效负载){
        // 按摩
        this._super(store, type, payload);
      },
      规范化:函数(类型,哈希,属性){
        // 按摩
        this._super(类型,哈希,属性);
      }
    });
  • 当您的有效负载的顶层组织方式与 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 数据的 Ember 的更多信息:没有 Ember 数据的 Ember

于 2013-07-30T04:55:25.630 回答
7

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

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

  • /users.json(查找全部)
  • /users/view/1.json(查找)
  • /users/delete/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 数据。我希望他们有一个简单的例子,如何为不同的情况编写不同类型的适配器。

于 2013-09-19T07:28:45.413 回答
1

对于那些自己编写适配器的人,如果您需要从适配器返回一个值(例如,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

于 2015-06-25T17:17:04.003 回答