web-dev-qa-db-ja.com

ember.js用のカスタムアダプターはどのように作成しますか?

私はember.jsを使用することを計画していますが、私のREST apiはパッケージ化されたRESTアダプターと正確に一致しません。私はember findAllがページネーションのオプションなしですべてのドキュメントを取得する方法が嫌いなので、他のクエリパラメータとともに有用です私が自分でajaxを書きたいのはそのためです。

32
carboncomputed

Ember Data

これはEmber Data 1.0 beta 9の時点で最新です。

Ember Data Adaptersのいずれかを拡張します。サイト全体に拡張するには:

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){
 //マッサージ
 this._super (store、type、payload、id); 
}、
 extractArray:function(store、type、payload){
 //マッサージ
 this._super( store、type、payload); 
}、
 normalize:function(type、hash、property){
 // massage 
 this._super(type、hash 、プロパティ); 
} 
}); 
  • ペイロードのトップレベルがEmber Data expectsとは異なる方法で編成されている場合は、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

62
Kingpin2k

同じ問題がありました。私もバックエンド(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)

多くの髪を引っ張って、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データを使用しています。さまざまな状況に応じてさまざまなタイプのアダプターを作成する簡単な例があればいいのですが。

7
traviss0

アダプターを自分でコーディングするユーザーの場合、アダプターから値を返す必要がある場合(たとえば、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 promises here: https://hackhands.com/3-ways-ember-js-leverages-promises/ またはこちら- http://emberjs.com/api/classes/RSVP.Promise.html