使用复合密钥时,Backbone在更新时执行POST而不是PUT

时间:2013-03-04 10:39:22

标签: backbone.js model composite-key

我在模型中使用复合键,并根据我的复合键生成ID:

app.Assignment = Backbone.Model.extend({
    idAttribute : [ 'personId', 'jobId' ],
    parse : function(resp) {
        resp.id = resp.personId + "_" + resp.jobId;
        return resp;
    }
});

但是Backbone仍然认为Assignment的所有实例都是新的,尽管我在从API中获取它时在parse方法中设置了id。因此,Backbone没有DELETE,并且在更新时执行POST而不是PUT。我该如何解决这个问题或者“正确的方法”呢?

更新

看起来用this.id替换resp.id解决了这个问题。

3 个答案:

答案 0 :(得分:2)

Backbone.Model的parse方法的结果传递给set方法,该方法设置模型的属性。我认为,混淆点是模型的ID不是它的属性之一;它是属性之一。

那么,会发生什么:

  1. 您的原始数据从服务器返回并传递到parse
  2. 现在使用id属性进行扩充的相同原始数据将传递到set
  3. set看起来和您的idAttribute[ 'personId', 'jobId' ])以及原始数据中的所有密钥
  4. 由于这些密钥都不匹配idAttribute,因此没有一个密钥用作模型的ID,因此您就会遇到问题。
  5. 您在this.id内设置parse的解决方案有效,但它可能会导致问题,因为解析通常设计为对其输入(原始数据)进行操作,而不是修改模型本身;该部分应该在调用set时发生。更清洁的解决方案是做类似以下的事情:

    app.Assignment = Backbone.Model.extend({
        // note that no idAttribute is specified, leaving it as the default "id"
        parse : function(resp) {
            resp.id = resp.personId + "_" + resp.jobId;
            return resp;
        }
    }
    

    或者,如果你想要一个不同的ID属性......

    app.Assignment = Backbone.Model.extend({
        idAttribute: 'personAndJobId',
        parse : function(resp) {
            resp.personAndJobId = resp.personId + "_" + resp.jobId;
            return resp;
        }
    }
    

答案 1 :(得分:0)

除了此处的idAttribute问题之外,您始终可以通过传递给save()的类型选项强制Backbone使用某种HTTP方法。

model.save(null, { type: 'put' })

答案 2 :(得分:0)

我从未在Backbone中使用复合ID,但我认为这可以很容易地解决您的问题:

initialize: function() {
      this.set("id", this.generateID());
},
generateID = function () {
    return this.personId + + "_" + this.jobId;
}

在Backbone模型定义中使用此代码,您将为每个模型创建一个唯一的ID,您不应该遇到更新问题并保存它(并且您不需要设置任何idAttribute)。