我有两个模型(用户和任务),它们是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({
});
当我在FollowerCollection上进行提取时,我收到以下错误:
Uncaught TypeError: Cannot read property 'idAttribute' of undefined
在backbone-relation version 0.5.0
这里是一段backbone-relation.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)
有关,因为如果我发表评论,它就能正常运作
为什么?有什么想法吗?
答案 0 :(得分:3)
删除_.bindAll确实有效。
这是一种耻辱,因为它是一个非常方便的功能。它必须严重地与Backbone的某些部分进行交互。我在v9.10
我一直使用这种方法,有时只会出现问题(例如,当您想要批量添加到集合时)。
对我来说,问题在于Backbone.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 似乎当前的维护者不喜欢这种方法,但我不明白为什么。
答案 1 :(得分:0)
就像我的项目非常庞大,我不得不创建自定义bindAll。这里有代码,它适用于最新版本。 我绑定了实例“this”的所有属性,除了那些具有属性原型的属性,比如集合中的this.model
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);
};