【问题标题】:Backbone does POST instead of PUT on updates when composite key is used使用复合键时,Backbone 在更新时执行 POST 而不是 PUT
【发布时间】:2013-03-04 10:39:21
【问题描述】:

我在我的模型中使用复合键并根据我的复合键生成 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 可以解决问题。

【问题讨论】:

  • Backbone 不支持复合键,因此将idAttribute 定义为数组是无效的。每个模型都必须有一个 id 字段。您的资源 URL 是什么样的?
  • 它确实支持复合键:github.com/documentcloud/backbone/pull/1558 实际上我通过这样做解决了它 this.id = ... 而不是 resp.ide = ...
  • 啊,你使用的是github.com/caseywebdev/backbone-composite-keys。在问题中提及它是有道理的。
  • 不做解析的事情消除了使用复合键的原因吗?

标签: backbone.js model composite-key


【解决方案1】:

Backbone.Model 的parse 方法的结果被传递给设置模型的属性 的set 方法。我认为你的困惑点是模型的 ID 不是它的属性之一。这是它的属性之一。

那么,会发生什么:

  1. 您的原始数据从服务器返回并传递给parse
  2. 同样的原始数据,现在增加了id 属性,被传递给set
  3. set 看起来和你的 idAttribute ([ 'personId', 'jobId' ]) 以及原始数据中的所有键
  4. 由于这些键都不匹配 idAttribute,因此它们都不会用作模型的 ID,因此您遇到了问题。

您在parse 中设置this.id 的解决方案可行,但它可能会导致问题,因为解析通常设计为对其输入(原始数据)进行操作,而不是修改模型本身;当调用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;
    }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我从未在 Backbone 中使用复合 ID,但我认为这可能是您的问题的简单答案:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多