簡體   English   中英

如何為ember.js創建自定義適配器?

[英]How do you create a custom adapter for ember.js?

我打算使用ember.js,但我的REST api與打包的REST適配器並不完全一致。 我想“覆蓋”查找並能夠將自己的ajax放入其中。 我不喜歡一個余燼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) {
    // 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: 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);
      }
    });
  • 當有效負載的頂層組織方式與Ember Data期望的不同時,請使用extractSingle和extractArray
  • 如果有效負載中的所有子哈希都可以以相同的方式規范化,則使用no​​rmalize來規范化子哈希。
  • 使用normalizeHash來規范化特定的子哈希。
  • 如果你覆蓋extractSingle,extractArray或規范化,請確保調用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 without Ember Data

我有同樣的問題。 我也想用我的后端(cakePHP)稍微不同的格式,並且無法弄清楚如何做到這一點。 之前的答案很棒,但您可能不需要重新定義每個方法,只需通過覆蓋RESTAdapter中的buildURL來更改URL的格式。

例如,我想使用cakePHP的擴展,並希望我的網址看起來像這樣,應用程序范圍:

  • /users.json(findAll)
  • /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數據。 我希望他們有一個簡單的例子,說明如何為不同情況編寫不同類型的適配器。

對於自己編碼適配器的用戶,如果需要從適配器返回一個值(例如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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM