主干同步问题触发POST而不是PUT

时间:2015-05-13 07:39:00

标签: javascript jquery backbone.js underscore.js marionette

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

 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”请求。但主干正在发出POST请求,因为“ID”不存在。

我对骨干很新,我想知道无论如何都要与服务器同步而不必传递ID?我怎么解决这个问题? 我基本上想要发出PUT请求而不是发布URL请求。(因为我的后端只支持PUT请求)。

4 个答案:

答案 0 :(得分:3)

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

我觉得在您的情况下,您的模型中可能没有唯一属性,因此设置idAttribute可能是一项挑战。因此,我建议您不要在模型定义中指定idAttribute。相反,我们只是动态处理它。只需像这样重构你的代码:

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

答案 1 :(得分:2)

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

  

如果模型为New,则保存将为“create”(HTTP POST),如果是   模型已经存在于服务器上,保存将是“更新”(HTTP   PUT)。

你可能会尝试的是@Sami建议用更新请求覆盖保存(确实意识到这里的所有解决方案都是错误的/变通方法)。

如果你真的需要PUT并且因为某些神秘的理由接受POST而不能改变你的后端,你可以改变模型中的idAttribute。

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

要意识到你的后端非常可能存在设计缺陷,你正在改变并创建变通方法来处理它,你应该考虑避免它。

答案 2 :(得分:2)

我已使用此代码段。

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

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

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

答案 3 :(得分:0)

您可以覆盖save method。 像

这样的东西
   var model = Backbone.Model.extend({

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


   });