我有一个骨干模型:
var User = Backbone.Model.extend({
idAttribute: '_id',
url: '/api/user',
defaults:
{ username: ''
}
});
我拿来:
var user = new User();
user.fetch();
现在,在我的一个观点中,作为一个click
事件,我有这个:
toggleSubscription: function () {
user.set('subscriptions', true);
user.save();
}
这会导致POST请求。但是,该记录已经存在于服务器上,并且由于我获取了它(并且模型实例具有id
属性),我认为Backbone应该执行PUT而不是POST。为什么它可能会进行POST?
尝试检查user.isNew()
。
看起来您创建了一个没有ID的新模型,这就是它试图在Backbone.sync
期间添加ID的原因。
更新:
以上内容完全正确。它之所以执行POST
,是因为它是一个新模型(也就是说,它没有id)。在获取模型之前,您需要给它一个id。在您的示例中:
var user = new User();
user.fetch();
user.save(); // in XHR console you see POST
var user = new User({ id: 123 });
user.fetch();
user.save(); // in XHR console you see PUT
如果模型还没有id,则认为它是新的--http://backbonejs.org/#Model-isNew
如果模型还没有id,则认为它是新的。。。因此主干网将进行CCD_ 6请求而不是CCD_。
只需将type: 'POST'
添加到保存块即可覆盖此行为:
var fooModel = new Backbone.Model({ id: 1});
fooModel.save(null, {
type: 'POST'
});
使用urlRoot属性设置基本URL /api/user
。然后
- 保存未设置
_id
属性的模型时,它将POST到/api/user
以及 - 当您保存一个设置了
_id
属性的模型时,它会PUT到/api/user/{_id}
。请注意,它会自动将_id
值附加到基本URL
它将查找_id
属性的值,因为您已将该值设置为idAttribute
。
服务器响应必须是这样的:
{
_id : 111
}
因为您将_id设置为主键。获取模型时,请验证_id的值,它必须具有一个值:console.log(model.get('_id'));
我的想法是,您在主干模型中设置了"_id"作为主键,但服务正在返回您的"id"
更新:添加正常行为的示例代码:
var UserModel = Backbone.Model.extend({
idAttribute: '_id',
url: '/api/user',
defaults:
{ username: ''
}
});
user = new UserModel({_id : 20});
user.save();
user = new UserModel();
user.save();
输出:PUT/api/user 405(不允许使用方法)POST/api/user 404(未找到)
检查Model的第一个实例是如何具有id的,并且它尝试执行PUT而不是另一个POST。我无法重现您的问题,所以我认为问题出在您的服务器响应上。
可能值得检查emulateHTTP
是否为真。这将通过添加_method
标头将所有PUT更改为POST(您可能还想检查是否存在此标头以确认此想法)。