31 votes

Backbone.js Modeler une URL différente pour créer et mettre à jour?

disons que j'ai une épine Dorsale Modèle et je crée une instance d'un modèle comme celui-ci:

var User = Backbone.Model.extend({ ... });
var John = new User({ name : 'John', age : 33 });

Je me demande si c'est possible, si j'utilise John.save() à la cible /user/create lorsque j'utilise John.save() sur le deuxième temps (mise à jour/METTRE) à la cible /user/update lorsque j'utilise John.fetch() à la cible /user/get et quand j'utilise John.remove() à la cible /user/remove

Je sais que je pourrais définir John.url à chaque fois avant que je déclenchement de la méthode, mais je me demandais si l'on pouvait se faire automatiquement d'une façon ou sans substituant la colonne vertébrale de la méthode.

Je sais que je pourrais utiliser une url de la forme /user/handle et de gérer la demande en fonction de la méthode de requête (GET/POST/PUT/DELETE) mais je me demandais simplement si il y a un moyen d'avoir autre url, par l'action de la colonne vertébrale.

Merci!

78voto

dzejkej Points 5582

Les méthodes d' .fetch(), .save() et .destroy() sur Backbone.Model sont de vérifier si le modèle a .sync() défini, et si oui, il sera appelée autrement, Backbone.sync() sera appelée (voir les dernières lignes du code source).

Ainsi, l'une des solutions est de mettre en oeuvre .sync() méthode.

Exemple:

var User = Backbone.Model.extend({

  // ...

  methodToURL: {
    'read': '/user/get',
    'create': '/user/create',
    'update': '/user/update',
    'delete': '/user/remove'
  },

  sync: function(method, model, options) {
    options = options || {};
    options.url = model.methodToURL[method.toLowerCase()];

    return Backbone.sync.apply(this, arguments);
  }
}

2voto

Michael Kropat Points 3993

Pour résumer la solution de dzejkej un niveau plus loin, vous pouvez encapsuler la fonction Backbone.sync pour interroger le modèle pour les URL spécifiques à la méthode .

 function setDefaultUrlOptionByMethod(syncFunc)
    return function sync (method, model, options) {
        options = options  || {};
        if (!options.url)
            options.url = _.result(model, method + 'Url'); // Let Backbone.sync handle model.url fallback value
        return syncFunc.call(this, method, model, options);
    }
}
 

Ensuite, vous pouvez définir le modèle avec:

 var User = Backbone.Model.extend({
    sync: setDefaultUrlOptionByMethod(Backbone.sync),
    readUrl: '/user/get',
    createUrl: '/user/create',
    updateUrl: '/user/update',
    deleteUrl: '/user/delete'
});
 

1voto

dlamotte Points 2912

Faites-vous affaire avec un RESTE de mise en œuvre qui n'est pas à des spécifications ou des besoins d'une sorte de solution de contournement?

Au lieu de cela, pensez à utiliser l' emulateHTTP option trouvé ici:

http://documentcloud.github.com/backbone/#Sync

Sinon, vous aurez probablement juste besoin de remplacer la valeur par défaut Backbone.sync méthode et vous serez bon d'aller si vous voulez obtenir une vraie folle avec ça... mais je ne suggère pas que. Il serait préférable d'utiliser une véritable interface RESTful.

0voto

Andreas Köberle Points 16453

Non, vous ne pouvez pas le faire par défaut avec la colonne vertébrale. Ce que vous pourriez faire est d'ajouter le modèle qui va changer le modèle d'url sur chaque événement, le modèle de déclencheur. Mais ensuite, vous avez toujours le problème que bckbone utilisera POST ajouter la première fois que le modèle a été enregistré et PUT pour chaque appel par la suite. Si vous avez besoin de remplacer l' save() méthode ou Backbone.sync ainsi.

Après tout, il ne semble pas une bonne idée de faire cette cause il briser l' REST modèle de base est à construire.

0voto

mlunoe Points 1490

Je me suis inspiré de cette solution, où vous créez simplement votre propre appel ajax pour les méthodes qui ne sont pas destinées à récupérer le modèle. En voici une version allégée:

 var Backbone = require("backbone");
var $ = require("jquery");
var _ = require("underscore");

function _request(url, method, data, callback) {
  $.ajax({
    url: url,
    contentType: "application/json",
    dataType: "json",
    type: method,
    data:  JSON.stringify( data ),
    success: function (response) {
      if ( !response.error ) {
        if ( callback && _.isFunction(callback.success) ) {
          callback.success(response);
        }
      } else {
        if ( callback && _.isFunction(callback.error) ) {
          callback.error(response);
        }
      }
    },
    error: function(mod, response){
      if ( callback && _.isFunction(callback.error) ) {
        callback.error(response);
      }
    }
  });
}

var User = Backbone.Model.extend({

  initialize: function() {
    _.bindAll(this, "login", "logout", "signup");
  },

  login: function (data, callback) {
    _request("api/auth/login", "POST", data, callback);
  },

  logout: function (callback) {
    if (this.isLoggedIn()) {
      _request("api/auth/logout", "GET", null, callback);
    }
  },

  signup: function (data, callback) {
    _request(url, "POST", data, callback);
  },

  url: "api/auth/user"

});

module.exports = User;
 

Et puis vous pouvez l'utiliser comme ceci:

 var user = new User();

// user signup
user.signup(data, {
  success: function (response) {
    // signup success
  }
});

// user login
user.login(data, {
  success: function (response) {
    // login success
  }
});

// user logout
user.login({
  success: function (response) {
    // logout success
  }
});

// fetch user details
user.fetch({
  success: function () {
    // logged in, go to home
    window.location.hash = "";
  },
  error: function () {
    // logged out, go to signin
    window.location.hash = "signin";
  }
});
 

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