バックボーンモデルがあり、次のようなモデルのインスタンスを作成するとします。
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を使用する方法があるかどうか疑問に思っています。
ありがとう!
メソッド .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);
}
}
_
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'
});
REST実装ではない、または何らかの回避策が必要な実装を扱っていますか?
代わりに、ここにあるemulateHTTP
オプションの使用を検討してください:
http://documentcloud.github.com/backbone/#Sync
それ以外の場合は、おそらくデフォルトのBackbone.sync
メソッドをオーバーライドするだけで十分です。これに夢中になりたい場合は、問題ありませんが、お勧めしません。真のRESTfulインターフェースを使用するのが最善です。
いいえ、デフォルトではバックボーンを使用してこれを行うことはできません。あなたができることは、モデルがトリガーするすべてのイベントでモデルのURLを変更するモデルに追加することです。しかし、その場合は常に、モデルが最初に保存されたときにbckboneがPOST
addを使用し、その後のすべての呼び出しでPUT
を使用するという問題があります。したがって、save()
メソッドまたはBackbone.sync
もオーバーライドする必要があります。
結局、これを行うことは、バックボーンが構築されているREST
パターンを破壊するので、良い考えではないようです。
私は 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";
}
});