Backbone model.save()导致POST而不是PUT

时间:2012-07-20 21:33:41

标签: backbone.js

我有一个Backbone模型:

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呢?

5 个答案:

答案 0 :(得分:7)

尝试检查user.isNew()

看起来你创建了一个没有ID的新模型,这就是为什么它试图在Backbone.sync期间添加它。

<强>更新

以上是完全正确的。它确实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

答案 1 :(得分:3)

  

如果模型还没有id,则认为它是新的。 - http://backbonejs.org/#Model-isNew

如果模型还没有id,则认为它是新的......因此,骨干网将执行PUT请求而不是POST

只需将type: 'POST'添加到保存区块即可覆盖此行为:

var fooModel = new Backbone.Model({ id: 1});

fooModel.save(null, {
  type: 'POST'
});

答案 2 :(得分:2)

使用urlRoot属性设置基本网址/api/user。然后

  1. 当您保存未设置/api/user属性的模型时,它将POST到_id
  2. 当您保存具有/api/user/{_id}属性集的模型时,它将PUT到_id。请注意,它会自动将_id值附加到基本网址。
  3. 它会查找_id属性的值,因为您已将该值设置为idAttribute

答案 3 :(得分:1)

服务器响应必须采用这种方式:

{
  _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(未找到)

检查模型的第一个实例如何具有id,并尝试执行PUT但是另一个POST。我无法重现您的问题,所以我的想法是问题在于您的服务器响应。

答案 4 :(得分:0)

可能值得检查emulateHTTP是否属实。这将使用添加的_method标题将您的所有PUT更改为POST(您可能还需要检查这是否存在以确认该想法)。