我有两个模型(用户和任务),它们是Backbone.RelationalModel
的实例。
关于这两个模型的关系如下:
// Task model
var Task = Backbone.RelationalModel.extend({
relations: [
{
type: 'HasOne',
key: 'user',
relatedModel: User
}
],
urlRoot: 'someUrl'
});
然后我有一个集合,其代码如下所示:
var FollowerCollection = Backbone.Collection.extend({
initialize: function () {
_.bindAll(this);
}
model: User
});
var User = Backbone.RelationalModel.extend({
});
当我在关注者收藏上进行获取时,出现以下错误:
Uncaught TypeError: Cannot read property 'idAttribute' of undefined
在主干关系的1565行上.js backbone-relation version 0.5.0
这里有一段骨干关系的代码.js
if ( !( model instanceof Backbone.Model ) ) {
// Try to find 'model' in Backbone.store. If it already exists, set the new properties on it.
var existingModel = Backbone.Relational.store.find( this.model, model[ this.model.prototype.idAttribute ] );
问题与_.bindAll(this)
有关,因为如果我评论它,它会正常工作。
为什么?有什么想法吗?
删除 _.bindAll 确实有效。
很遗憾,因为它是一个非常方便的功能。它必须与 Backbone 的某些部分进行不良交互。我在v9.10上
我一直使用这种方法,问题只是偶尔出现(例如当您想批量添加到集合时)。
对我来说,问题出在这个骨干.js方法上:
// Get a model from the set by id.
get: function(obj) {
if (obj == null) return void 0;
this._idAttr || (this._idAttr = this.model.prototype.idAttribute);
return this._byId[obj.id || obj.cid || obj[this._idAttr] || obj];
},
代码在this.model.prototype
失败,因为原型未定义。什么?你。对于真实。
问题是,当调用 _.bindAll 时,它会绑定集合的所有属性,如@jakee所说。这似乎包括Collection.model,我认为这是一个错误。
解决方案是绑定各个方法,直到此问题得到解决。
github上有一个现有但已关闭的问题:https://github.com/documentcloud/backbone/issues/2080似乎当前的维护者不喜欢这种方法,但我不明白为什么。
就像我的项目真的很大一样,我必须创建自定义 bindAll。这里有代码,它适用于最新版本。我绑定了实例"this"的所有属性,除了那些具有带有属性的原型的属性,例如 this.model in a Collection
https://gist.github.com/patrixd/8025952
//bindAll from underscore that allows 1 argument to bind all the functions from the prototype,
//or if there are more arguments they will be the only binded
_.originalBindAll = _.bindAll;
_.bindAll = function (that) {
var funcs = Array.prototype.slice.call(arguments, 1),
validKeys = [], fn;
if (funcs.length == 0) {
for (var i in that) {
fn = that[i];
if (fn && typeof fn == "function" && (!fn.prototype ||
_.keys(fn.prototype).length == 0))
validKeys.push(i);
}
_.originalBindAll.apply(_, [that].concat(validKeys));
}
else
_.originalBindAll.apply(_, arguments);
};