web-dev-qa-db-fra.com

Comment créez-vous un adaptateur personnalisé pour ember.js?

Je prévois d'utiliser ember.js, mais mon API REST ne s'aligne pas exactement avec l'adaptateur REST fourni. Je voudrais "annuler" trouver et pouvoir y mettre mon propre ajax. Je n'aime pas la façon dont une recherche de braises récupère tous mes documents sans option de pagination, ce qui est utile, ainsi que d'autres paramètres de requête, ce qui explique pourquoi je veux écrire mon propre fichier ajax. Je suis incapable de trouver de la documentation sur la manière dont je procéderais.

32
carboncomputed

Pour les données de braise

Ceci est à jour depuis Ember Data 1.0 beta 9.

Étendre l’un des adaptateurs de données Ember. Pour rendre le site large:

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

Pour le rendre spécifique au modèle:

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

Vous définissez ensuite l'implémentation que vous souhaitez remplacer. Vous avez toujours la possibilité d'appeler this._super et de revenir à l'implémentation de base. par exemple.

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

Ou vous pouvez remplacer complètement l'implémentation:

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

Pour voir l’API complète que vous pouvez remplacer, voir: http://emberjs.com/api/data/classes/DS.RESTAdapter.html

Sérialiseur

Il est souvent plus important de lancer votre propre sérialiseur pour masser les données afin de les adapter à votre point de terminaison du repos. Voici quelques informations utiles tirées du document de transition https://github.com/emberjs/data/blob/master/TRANSITION.md .

La version courte est qu’une fois la demande Ajax terminée, la charge résultante est envoyée par les points suivants:

  1. La charge est envoyée à extractSingle si la demande d'origine visait un seul enregistrement (comme find/save) ou extractArray si la requête d'origine visait un tableau d'enregistrements (comme findAll/findQuery).
  2. Le comportement par défaut de ces méthodes consiste à séparer le niveau supérieur de la charge utile en plusieurs enregistrements plus petits.
  3. Chacun de ces enregistrements plus petits est envoyé à la normalisation, ce qui permet de normaliser un enregistrement à la fois.
  4. Enfin, certains types d’enregistrements peuvent être spécialement normalisés.
 App.PostSerializer = DS.RESTSerializer.extend ({
 ExtractSingle: fonction (magasin, type, charge utile, id)) {
 // massage 
 This._super (magasin, type, charge utile, id) ;
}, 
 extractArray: fonction (magasin, type, charge) {
 // massage 
 this._super (magasin, type, charge); type, hachage, propriété) {
 // massage 
 this._super (type, hachage, propriété); 
} 
}); 
  • utilisez extractSingle et extractArray lorsque le niveau supérieur de votre charge utile est organisé de manière différente de celle attendue par Ember Data
  • utilisez normalize pour normaliser les sous-hachages si tous les sous-hachages de la charge utile peuvent être normalisés de la même manière.
  • utilisez normalizeHash pour normaliser des sous-hachages spécifiques.
  • assurez-vous d'appeler super si vous écrasez extractSingle, extractArray ou normalize pour que le reste de la chaîne soit appelé.

Rouler le vôtre

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

Puis de votre itinéraire, ou de n'importe où

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

Personnellement, j’injecterais l’adaptateur sur les itinéraires simplement pour me faciliter la vie:

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

Ensuite, sur la route, vous pourriez être plus paresseux et faire:

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

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

Pour en savoir plus sur Ember sans Ember Data: Ember sans Ember Data

62
Kingpin2k

J'ai eu le même problème. Moi aussi, je voulais utiliser un format légèrement différent avec mon backend (cakePHP) et je ne savais pas comment le faire. Les réponses précédentes sont excellentes, mais vous n'avez peut-être pas besoin de redéfinir chaque méthode, mais simplement de changer le format de l'URL en redéfinissant l'URL de construction dans l'adaptateur REST.

Par exemple, je veux utiliser l'extension de cakePHP et que mes URL ressemblent ainsi à l'échelle de l'application:

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

Après avoir tiré beaucoup de cheveux et réalisé que les données de la braise étaient essentielles, j'ai utilisé le code suivant:

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

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

    url += '.json';

    return url;
  }
});

Les documents Ember sont bons, mais la plupart de leurs exemples utilisent des données FIXTURE. Je souhaite qu'ils aient un exemple simple comment écrire différents types d'adaptateurs pour différentes situations.

7
traviss0

Pour ceux qui codent eux-mêmes l'adaptateur, si vous devez renvoyer une valeur de votre adaptateur (par exemple, userId), vous pouvez renvoyer json ou promise. Voici un exemple de retour de promesse:

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

Vous pouvez obtenir plus d'informations sur les promesses Ember ici: https://hackhands.com/3-ways-ember-js-leverages-promises/ ou ici http://emberjs.com/api/classes/ RSVP.Promise.html

1