Backbone 为自定义 id 属性提供未定义

Backbone giving undefined for custom id attribute

我的数据库中有一个由 id 和 version 组成的组合键。我对同一记录的不同版本使用相同的 ID。 Backbone 正在合并具有相同 ID 的模型,因为它们具有相同的 ID。所以在四处看看之后,我修改了模型的解析函数。

parse: function(response, options) {
  response.id = response.id + '_' + response.version;
  return response;
}

这非常简单,一切正常,我可以显示具有相同 ID 和不同版本的多条记录。当我尝试保存我的模型时,奇怪的行为开始了。在我看来,我有一个 saveClickHandler,它将模型发送到后端进行存储。

onSaveClick: function(e){
  // Some form validation which is not very relevant I think
  var self = this,
  data = {
    enabled:      Input.isChecked('enabled', this.$el)? true: false,
    days:         Input.get('days', this.$el),
    from_name:    Input.get('from_name', this.$el),
    reply_to:     Input.get('reply_to', this.$el),
    subject:      Input.get('subject', this.$el),
    content_html: Input.get('message', this.$el),
    postmark_tag: Input.get('postmark_tag', this.$el)
  };

  this.model.save(data, {
    url: Application.Config.URL_API + '/emails/' + self.model.get('id').split('_')[0] + '/' + self.model.get('id').split('_')[1],
  });
}

第一次加载页面并存储记录后,一切正常,记录在数据库中更新等等。但是第二次请求失败,因为 id 未定义。

实际上,甚至在进行保存之前,我就记录了视图的模型,并且正在更改 id,例如10_1 到 undefined_undefined。我没有明确修改模型本身,所以我想它与 backbone 以某种方式修改它有关。

有人知道我遇到的问题是什么吗?

我认为您的架构在这里可能不是最理想的。更改模型的 ID 是一个问题的解决方案,可以通过设计您的应用程序和 api 来处理版本差异来更好地解决这个问题。此外,您还错过了 Backbone 的约定优于配置理念的好处。

每个数据库记录一个模型和一个 ID,由一个资源端点访问应该是目标。这可以通过几种方式解决。

让您的 API return 模型除了当前值之外还具有版本历史记录:

// GET /model response

{
  "id",
  "foo" : "foo",
  "bar" : "bar",
  "versions" : [
    {
      "version_id" : 1,
      "foo" : "foo1",
      "bar" : "bar1"
    },
    {
      "version_id" : 2,
      "foo" : "foo2",
      "bar" : "bar2"
    }
  ]
}

感谢您仍然可以在保留版本历史记录的同时收听模型属性当前值的更改事件。

另一种可能更合适的解决方法是使用一个集合,并让 API return 每个版本都有一个单独的模型。对于 API 这也是一种更简洁的 REST 方法,因为模型及其版本都有自己的端点,例如/model/version 和所有 Backbone 的内置 CRUD 操作都可以正常运行,而无需覆盖任何内容。

在尝试了更多东西之后,似乎当我提交对特定记录的更新时,我收到了这样的回复:

{"success":true,"code":204,"message":"ok","result":null}

所以我想看看我实现的 parse() 是否搞砸了。所以我将解析更改为:

parse: function(response, options) {
    if (response.id){
        response.id = response.id + '_' + response.version;
        return response;
    }
}

经过测试,似乎一切正常。所以我想由于结果为空,它找不到 ID,因此 undefined_undefined。实际上,这一切现在都说得通了。

感谢你们两位的回复,希望这可以为将来的人节省一些时间。