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


Je compte utiliser ember.js, mais mon api REST ne correspond pas exactement à l'adaptateur REST intégré. Je voudrais "remplacer" trouver et être capable d'y mettre mon propre ajax. Je n'aime pas comment un findAll ember récupère tous mes documents sans options pour la pagination, de sorte que avec d'autres paramètres de requête serait utile - c'est pourquoi je veux écrire mon propre ajax. Je n'ai pas été en mesure de trouver de documentation sur la façon dont j'y arriverais.


31
2017-07-30 04:25


origine


Réponses:


Pour les données Ember

Ceci est à jour depuis Ember Data 1.0 beta 9.

Étendez l'un des adaptateurs de données Ember. Pour le rendre accessible à tous:

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

Pour le rendre spécifique au modèle:

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

Vous définirez ensuite l'implémentation que vous souhaitez remplacer. Vous avez toujours la possibilité d'appeler this._super et revenir à la mise en œuvre 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 complètement remplacer 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 le api complet, vous pouvez remplacer: http://emberjs.com/api/data/classes/DS.RESTAdapter.html

Sérialiseur

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

La version courte est qu'une fois qu'une requête Ajax est terminée, la charge utile résultante est envoyée via les hooks suivants:

  1. Le payload est envoyé à extractSingle si la requête d'origine était pour un enregistrement unique (comme find / save) ou extractArray si la requête d'origine était pour 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, des types spécifiques d’enregistrements peuvent être spécialement normalisés.
    App.PostSerializer = DS.RESTSerializer.extend ({
      extractSingle: function (store, type, payload, id) {
        // massage
        this._super (store, type, payload, id);
      },
      extractArray: function (store, type, charge utile) {
        // massage
        this._super (store, type, charge utile);
      },
      normalize: function (type, hash, propriété) {
        // massage
        this._super (type, hachage, propriété);
      }
    })
  • utilisez extractSingle et extractArray lorsque le niveau supérieur de votre charge utile est organisé différemment de ce que prévoit Ember Data
  • Utilisez la normalisation 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 remplacez extractSingle, extractArray ou normalise 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);
  }
});

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

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

Maintenant, personnellement, j'injecterais l'adaptateur sur les routes 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 l'itinéraire, 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

Vous pouvez en savoir plus sur Ember sans données Ember: Ember sans données Ember


61
2017-07-30 04:55



J'ai eu le même problème. Je voulais aussi utiliser un format légèrement différent avec mon backend (cakePHP) et je ne pouvais pas trouver 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 remplaçant la buildURL dans RESTAdapter.

Par exemple, je veux utiliser l’extension de cakePHP et je veux que mes urls se présentent 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 pris conscience que les données sur les braises sont 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 d'Ember sont bons, mais la plupart de leurs exemples utilisent des données FIXTURE. Je souhaite qu'ils aient un exemple simple sur la façon d'écrire différents types d'adaptateurs pour différentes situations.


7
2017-09-19 07:28



Pour ceux qui codent eux-mêmes l'adaptateur, si vous devez renvoyer une valeur à partir de votre adaptateur (par exemple, userId), vous pouvez retourner json ou promis. 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 d'Ember ici: https://hackhands.com/3-ways-ember-js-leverages-promises/ ou ici http://emberjs.com/api/classes/RSVP.Promise.html


1
2018-06-25 17:17