Backbone 同步问题触发 POST 而不是 PUT

Backbone sync issue firing POST instead of PUT

我在我的模型中编写了以下代码:

 urlroot: '/url/sms',
setAuthId: function(value) {

    var _this = this ;

     if (this.get("smsauth") != value) {

        this.set("smsauth",value);
        this.save();

//Ideally, I want to achieve this AJAX call request with backbone.

         // $.ajax({
         //     url: "/url/sms",
         //     data: value,
         //     type: 'PUT',
         //     processData: false,
         //     success: function(result) {
         //        _this.set("authId", value);

         //     },
         //    error : function(){
         //        console.log('Error setting authid');
         //    }
         // });
     }

 },

理想情况下,我们应该每次都触发一个 "PUT" 请求。但是 backbone 正在触发 POST 请求,因为 "ID" 不存在。

我是 backbone 的新手,我想知道是否有无需传递 ID 即可与服务器同步的方法?我怎么解决这个问题? 我基本上想为 URL. 发出 PUT 请求而不是 post 请求(因为我的后端只支持 PUT 请求)。

您可以覆盖 save method。 像

   var model = Backbone.Model.extend({

         save: function(options){
             return Backbone.sync("update", this, options);
         }


   });

我不太清楚你在保存什么。您使用 POST 处理的事实表明它是一个新条目。引用 docs 这种行为是正确的。 PUT 是更新,POST 是创建(在 CRUD 操作下)。

If the model isNew, the save will be a "create" (HTTP POST), if the model already exists on the server, the save will be an "update" (HTTP PUT).

您可以尝试@Sami 建议的方法,即用更新请求覆盖保存(请注意这里的所有解决方案都是 incorrect/workarounds)。

如果您确实需要 PUT 并且由于某些神秘原因无法更改后端以接受 POST,您可以更改模型中的 idAttribute。

var smsModel = Backbone.Model.extend({
   idAttribute: "smsauth" // for example
});

请注意您的后端很可能存在设计缺陷,您正在更改并创建解决方法来使用它,您应该考虑避免这种情况。

强制 Backbone.Model.save() 执行 PUT 的唯一真正方法是 @dbf 解释的方式,您必须设置您的 idAttribute。要正确设置 idAttribute 您的模型 应该 具有唯一的属性。 (这不是硬性要求,因为 model.isNew() 只是检查您的模型是否有一个名为 id属性 或您提供给模型的任何字符串idAttribute 属性。它不检查唯一性)。

我感觉到在您的情况下,您的模型中可能没有独特的属性,因此设置 idAttribute 可能是一个挑战。因此,我建议您不要在模型定义中指定 idAttribute。相反,我们只是处理它 dynamically.Just 像这样重构您的代码:

setAuthId: function(value) {
    var _this = this ;

     if (this.get("smsauth") != value) {
        // any model attribute is fine, we just need to return a prop
        this.prototype.idAttribute = "smsauth" 
        this.save("smsauth",value) // Save will do a set before the server request
         // model.save returns a promise. Here we'll reset the idAttribute
         .then(/* success handler */ function (response) { 
             _this.set("authId",value);
             _this.prototype.idAttribute = 'id' // You can set this to "authId" if that 
                                                // uniquely identifies this model
         },/* error handler */  function (response) { 
             _this.prototype.idAttribute = 'id' // reset idAttribute to default
         });
     }
}

我用过这个片段。

this.save({}, {
  type: 'PUT'
});

我发现你所有的答案都非常吸引人,我会尝试每个答案。

感谢您的建议,这就是我喜欢 SO 的原因。要学习的新东西。