2012-06-29 44 views
6

我有兩個模型(用戶和任務),它們是Backbone.RelationalModel的實例。_.bindAll(this)和Uncaught TypeError:無法讀取骨幹關係.js中未定義的屬性'idAttribute'

有關這兩種模式的關係如下:

// 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的backbone-relation version 0.5.0


這裏一塊骨架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)線1565,因爲如果我評論它,它工作正常。
爲什麼?有任何想法嗎?


+0

您確定,當您聲明關係時定義'User'模型嗎? –

+0

@mashingan我確實附加了關於任務模型的所有代碼。你能看看嗎?謝謝。 –

+0

您如何爲FollowerCollection和User添加代碼,以便我們甚至可以嘗試查找問題?目前我看不出這兩個班級之間有什麼關係。 – jakee

回答

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 似乎目前的維護人員不喜歡該方法,但我不明白爲什麼。

0

就像我的項目真的很大,我必須創建自定義的bindAll。這裏你有代碼,它與最新版本一起工作。 我綁定實例「this」的所有屬性,除了具有屬性原型的屬性外,像這樣。模型集合中的

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); 

};

相關問題