我是骨干的新手。
在我无法将某些模型添加到集合中并且有时使用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
。
有更好的想法吗?
答案 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
时会返回其条目。
nikoshr在answer below中有一个很好的解决方案。