web-dev-qa-db-ja.com

Backbone.js作成と更新で異なるURLをモデル化しますか?

バックボーンモデルがあり、次のようなモデルのインスタンスを作成するとします。

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

John.save()を使用して/user/createをターゲットにするときに、John.save()を2回目に使用するときに(update/PUT)、/user/updateをターゲットとしてJohn.fetch()を使用することは可能ですか? /user/getをターゲットにし、John.remove()を使用して/user/removeをターゲットにする場合

メソッドをトリガーする前に毎回John.urlを定義できることはわかっていますが、Backboneメソッドをオーバーライドせずに、なんらかの方法で自動的に発生するのではないかと思っています。

/user/handleのような1つのURLを使用して、リクエストメソッド(GET/POST/PUT/DELETE)に基づいてリクエストを処理できることはわかっていますが、バックボーンのアクションごとに異なるURLを使用する方法があるかどうか疑問に思っています。

ありがとう!

32
panosru

メソッド .fetch().save() および__ .destroy() on _Backbone.Model_はモデルに.sync()が定義されているかどうかを確認し、そうであればそれが呼び出されます。そうでない場合はBackbone.sync()が呼び出されます(リンクされたソースコードの最後の行を参照)。

したがって、解決策の1つは.sync()メソッドを実装することです。

例:

_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);
  }
}
_
78
kubetz

dzejkej'sソリューションをさらに1レベル抽象化するには、Backbone.syncメソッド固有のURLのモデルをクエリする関数。

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

次に、次のようにモデルを定義できます。

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

REST実装ではない、または何らかの回避策が必要な実装を扱っていますか?

代わりに、ここにあるemulateHTTPオプションの使用を検討してください:

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

それ以外の場合は、おそらくデフォルトのBackbone.syncメソッドをオーバーライドするだけで十分です。これに夢中になりたい場合は、問題ありませんが、お勧めしません。真のRESTfulインターフェースを使用するのが最善です。

1
dlamotte

いいえ、デフォルトではバックボーンを使用してこれを行うことはできません。あなたができることは、モデルがトリガーするすべてのイベントでモデルのURLを変更するモデルに追加することです。しかし、その場合は常に、モデルが最初に保存されたときにbckboneがPOST addを使用し、その後のすべての呼び出しでPUTを使用するという問題があります。したがって、save()メソッドまたはBackbone.syncもオーバーライドする必要があります。

結局、これを行うことは、バックボーンが構築されているRESTパターンを破壊するので、良い考えではないようです。

0

私は this ソリューションに触発されました。このソリューションでは、モデルをフェッチするためのものではないメソッドに対して独自のajax呼び出しを作成します。これを縮小したバージョンを次に示します。

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;

そして、あなたはこのようにそれを使うことができます:

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