it-swarm.com.de

Wie erstellen Sie einen benutzerdefinierten Adapter für ember.js?

Ich plane, ember.js zu verwenden, aber meine REST - API stimmt nicht genau mit dem gepackten REST - Adapter überein. Ich würde gerne "übersteuern" finden und meinen eigenen Ajax darin einsetzen können. Ich mag es nicht, wie ein ember findAll alle meine Dokumente abruft, ohne dass eine Option zur Paginierung erforderlich ist, so dass zusammen mit anderen Abfrageparametern nützlich wäre - weshalb ich mein eigenes Ajax schreiben möchte. Ich konnte keine Dokumentation finden, wie ich dies tun würde.

32
carboncomputed

Für Glutdaten

Dies ist seit Ember Data 1.0 Beta 9 auf dem neuesten Stand.

Erweitern Sie einen der Ember-Datenadapter. Um es für die ganze Site zu machen:

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

Um es modellspezifisch zu machen:

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

Dann definieren Sie die Implementierung, die Sie überschreiben möchten. Sie haben immer die Möglichkeit, this._super aufzurufen und zur Basisimplementierung zurückzukehren. z.B.

App.NotesAdapter = DS.RESTAdapter.extend({
  find: function(store, type, id) {
    id = "foo" + id;
    return this._super(store, type, id);
  }
});

Oder Sie können die Implementierung vollständig überschreiben:

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 } });
  },
   .....
});

Um die vollständige API anzuzeigen, können Sie sie überschreiben: http://emberjs.com/api/data/classes/DS.RESTAdapter.html

Serializer

Wichtiger ist oft das Rollen Ihres eigenen Serialisierers, um die Daten an Ihren Ruheendpunkt anzupassen. Hier sind einige nützliche Informationen aus dem Umstellungsdokument https://github.com/emberjs/data/blob/master/TRANSITION.md .

Die kurze Version ist, dass nach Abschluss einer Ajax-Anforderung die resultierende Nutzlast über die folgenden Haken gesendet wird:

  1. Die Payload wird an extractSingle gesendet, wenn es sich bei der ursprünglichen Anforderung um einen einzelnen Datensatz handelte (z. B. Suchen/Speichern) oder extractArray, wenn sich die ursprüngliche Anfrage auf ein Array von Datensätzen bezog (wie findAll/findQuery).
  2. Das Standardverhalten dieser Methoden besteht darin, die oberste Ebene der Nutzdaten in mehrere kleinere Datensätze aufzuteilen.
  3. Jeder dieser kleineren Datensätze wird zur Normalisierung gesendet, wodurch jeweils ein Datensatz normalisiert werden kann.
  4. Schließlich können bestimmte Arten von Datensätzen speziell normalisiert werden.
 App.PostSerializer = DS.RESTSerializer.extend ({
 ExtractSingle: function (Speicher, Typ, Nutzlast, ID) {
 // massage 
 This._super (Speicher, Typ, Nutzlast, ID) ;
}, 
 extractArray: Funktion (Laden, Typ, Nutzlast) {
 // Massage 
 this._super (Laden, Typ, Nutzlast); 
}, 
 normalize: Funktion ( Typ, Hash, Eigenschaft) {
 // Massage 
 this._super (Typ, Hash, Eigenschaft); 
} 
}); 
  • verwenden Sie extractSingle und extractArray, wenn die oberste Ebene Ihrer Nutzdaten anders organisiert ist, als es Ember Data erwartet
  • verwenden Sie normalize, um untergeordnete Hashwerte zu normalisieren, wenn alle untergeordneten Hashwerte in der Nutzlast auf dieselbe Weise normalisiert werden können.
  • verwenden Sie normalizeHash, um bestimmte Unterhashes zu normalisieren.
  • stellen Sie sicher, dass Sie super aufrufen, wenn Sie extractSingle, extractArray oder Normalize überschreiben, damit der Rest der Kette aufgerufen wird.

Selbst rollen

App.FooAdapter = Ember.Object.extend({
  find: function(id){
    return $.getJSON('http://www.foolandia.com/foooo/' + id);
  }
});

Dann von Ihrer Route oder von wo auch immer

App.FooRoute = Ember.Route.extend({
  model: function(){
    var adapter = App.FooAdapter.create();
    return adapter.find(1);
  }
});

Jetzt persönlich würde ich den Adapter auf die Routen spritzen, um mir das Leben zu erleichtern:

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");
    }
});

Dann könnten Sie auf der Route fauler sein und tun:

App.FooRoute = Ember.Route.extend({
  model: function(){
    return this.fooAdapter.find(1);
  }
});

Beispiel: http://emberjs.jsbin.com/OxIDiVU/676/edit

Sie können mehr über Glut ohne Glutdaten lesen: Glut ohne Glutdaten

62
Kingpin2k

Ich hatte das gleiche Problem. Auch ich wollte mit meinem Backend (cakePHP) ein etwas anderes Format verwenden und konnte nicht herausfinden, wie es geht. Die vorherigen Antworten sind großartig, aber Sie müssen möglicherweise nicht jede Methode neu definieren. Sie müssen lediglich das Format der URL ändern, indem Sie die buildURL im RESTAdapter überschreiben.

Zum Beispiel möchte ich die Erweiterung von cakePHP verwenden und möchte, dass meine URLs anwendungsweit so aussehen:

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

Nach vielem Ziehen an den Haaren und der Erkenntnis, dass Glutdaten wichtig sind, habe ich den folgenden Code verwendet:

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

    if (id) {
        url += '/' + id;
    }

    url += '.json';

    return url;
  }
});

Die Dokumente von Ember sind gut, aber die meisten Beispiele verwenden FIXTURE-Daten. Ich wünschte, sie hätten ein einfaches Beispiel, wie man verschiedene Arten von Adaptern für verschiedene Situationen schreibt.

7
traviss0

Wenn Sie einen Adapter selbst codieren, können Sie entweder Json oder Promise zurückgeben, wenn Sie einen Wert von Ihrem Adapter zurückgeben müssen (z. B. userId). Hier ist ein Beispiel für die Rückgabe von Versprechen:

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  
});

Weitere Informationen zu Ember-Versprechen erhalten Sie hier: https://hackhands.com/3-ways-ember-js-leverages-promises/ oder hier http://emberjs.com/api/classes/ RSVP.Promise.html