我的模型ID与cid相撞(例如:“c7”)

时间:2013-07-15 13:45:05

标签: backbone.js

我是骨干的新手。

在我无法将某些模型添加到集合中并且有时使用collection.get(id)获取错误模型后,我发现我的模型ID与主干cid发生冲突后非常困惑。

我的模型ID类似于“c7”或“c5e6”。虽然后者没有问题,但“c7”是骨干拥有该集合第七个元素的cid。

因此,如果我要求collection.get('c7')并期望null,我会获得由骨干提供cid“c7”的元素。如果我添加一个id为“c7”的元素,我将永远不会使用get("c7")将其恢复。

我想知道我是否是第一个遇到此问题的人,我没有找到关于骨干ID的语法限制的任何内容,有没有办法解决这个问题?作为一种解决方法,我会将自己的ID保存在自定义属性中,并且必须使用collection.where而不是collection.get

有更好的想法吗?

2 个答案:

答案 0 :(得分:3)

如果查看Backbone source code,您会看到模型中的cid由构造函数确定

this.cid = _.uniqueId('c');

c 是一个任意前缀,这意味着您可以通过覆盖_.uniqueId来消除您的ID歧义,例如

_._uniqueId = _.uniqueId;
_.uniqueId = function(prefix) {
    if (prefix === 'c') {
        prefix = 'cc';
    }
    return _._uniqueId(prefix);
};

没有覆盖:http://jsfiddle.net/nikoshr/KmNSr/及其:http://jsfiddle.net/nikoshr/KmNSr/1/

答案 1 :(得分:2)

不幸的是,这确实看起来像边缘情况问题而没有真正的解决方案。查看Backbone源代码,我们可以在Backbone.Collection.set方法中看到Backbone将您的ID及其内部CID混合在同一个对象中:

set: function(models, options) {
  // ...
  this._byId[model.cid] = model;
  if (model.id != null) this._byId[model.id] = model;
  // ...
  return this;
},

_byId对象包含导致您出现问题的所有ID。这是Backbone.Collection.get方法:

get: function(obj) {
  if (obj == null) return void 0;
  return this._byId[obj.id != null ? obj.id : obj.cid || obj];
},

当您使用不存在的ID(您自己的)(例如“c7”)调用它时,return ...行变为return this._byId["c7"];。由于_byId引用了您的和Backbone的ID,因此您在预期null时会返回其条目。

nikoshranswer below中有一个很好的解决方案。