6

我有两个模型(用户和任务),它们是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

在主干-relation.js 的第 1565 行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)因为如果我评论它,它可以正常工作。
为什么?有任何想法吗?


4

2 回答 2

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 似乎当前的维护者不喜欢这种方法,但我不明白为什么。

于 2013-02-20T03:21:39.137 回答
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);

};

于 2013-12-18T17:21:10.190 回答