3

我是骨干新手。

在对无法将我的一些模型添加到集合中并且有时使用错误的模型感到困惑之后,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.

有更好的想法吗?

4

2 回答 2

3

如果您查看Backbone 源代码,您会看到cid模型中的

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

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

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

没有覆盖: http: //jsfiddle.net/nikoshr/KmNSr/和它:http: //jsfiddle.net/nikoshr/KmNSr/1/

于 2013-07-15T15:27:54.893 回答
2

不幸的是,这看起来确实是一个没有真正解决方案的边缘案例问题。查看 Backbone 源代码,我们可以看到Backbone.Collection.setBackbone 将您的 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引用了您的 ID 和 Backbone 的 ID,因此您会在预期的时候返回他们的条目null

nikoshr在下面的答案中有一个很好的解决方案。

于 2013-07-15T14:23:55.970 回答