4 votes

Prédire le chemin absolu de l'URL dans Backbone.sync pour une API sur un autre serveur

Mon application Backbone communique avec une API qui existe sur un autre serveur. Backbone.sync générera des URL relatives par défaut. La façon la plus simple de faire précéder le chemin d'accès absolu du serveur serait quelque chose comme ce qui suit :

MyApp.BASE_URL = "https://api.someOtherSite.com"

class MyApp.Model extends Backbone.Model
  urlRoot: "#{MyApp.BASE_URL}/my_app_url"

Cependant, je préfère ne pas le faire car ce n'est pas DRY. J'ai pensé que je pourrais essayer quelque chose comme ce qui suit en remplaçant Backbone.sync :

do (Backbone) ->
  BASE_URL = 'https://api.someOtherSite.com'
  baseSync = Backbone.sync

  Backbone.sync = (method, model, options) ->
    url = _.result(model, 'url')
    options.url = "#{BASE_URL}/#{url}" if url && !options.url

    baseSync method, model, options

Toutefois, cela pose un problème pour d'autres parties du code, comme l'élément options passe partout. *(explication pour les intéressés en bas de page)

Existe-t-il un moyen propre et pratique de faire précéder le chemin d'accès au serveur de toutes les URL générées par l'application Backbone.sync ?


*Si le model qui est synchronisé est une instance de Backbone.Collection ce options sera transmis au constructeur du modèle de la collection. L'URL est l'une des rares propriétés qui sera directement attachée à un modèle si elle est transmise en tant que partie de l'attribut options objet. T sync pour tous les modèles qui sont créés dans une collection, car ils ont maintenant un ensemble d'URL attaché à eux au lieu d'une url qui génère une url appropriée en utilisant urlRoot ou de la collection url .

4voto

David Sulc Points 13259

Je pense que la meilleure option est de créer un modèle de base à partir duquel vos autres modèles s'étendront :

MyApp.Model = Backbone.Model.extend({
  urlRoot: function(){
             return 'https://api.someOtherSite.com/' + this.get('urlFragment')
  }
});

Et ensuite, vos modèles doivent être définis comme suit

MyApp.MyModel = MyApp.Model.extend({
  urlFragment: "my_model_url"
})

Donc, dans CoffeeScript :

class MyApp.Model extends Backbone.Model
  urlRoot: ->
           'https://api.someOtherSite.com/' + @get('urlFragment')

Et

class MyApp.MyModel extends MyApp.Model
  urlFragment: "my_model_url"

Maintenant, vous avez vos urls spécifiées de manière DRY !

1voto

Gamak Points 64

Vous devez utiliser les prototypes pour disposer d'une propriété universelle dans toutes les collections ou modèles, etc.

Backbone.Collection.prototype.absURL  = 'http://example.com';

var MyCollection = Backbone.Collection.extend({
model : myModel, 
url: function() {
    return this.absURL + '/api/stuff';
}
});

1voto

matt.kauffman23 Points 138

Je sais que c'est vieux, mais j'ai rencontré le problème en mettant en place un client pour une api que je développe. Ma solution, bien que sèche et très simple, se produit dans jQuery pas Backbone. Cela dit, jQuery est une dépendance de Backbone et je pense que c'est une approche raisonnable pour le cas typique.

$.ajaxPrefilter(function prependUrlPrefilter(opts) {
  opts.url = 'http://127.0.0.1:3000' + opts.url;
});

Un problème avec cette approche est qu'elle modifie globalement l'url de tous les appels xhr exécutés par jQuery. Si vous appelez des services web sur plusieurs domaines ou si vous avez des plugins qui le font et partagent votre même jQuery, vous devrez ajouter une condition ici.

Vous voudrez également abstraire la partie hôte du domaine dans une configuration.

Pour en savoir plus, consultez ajaxPrefilters. aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X