2012-06-29 13 views
6

Mam dwa modele (User and Task), które są instancjami Backbone.RelationalModel._.bindAll (this) and Uncaught TypeError: Nie można odczytać właściwości 'idAttribute' niezdefiniowanej w backbone-relation.js

Relacja o tych dwóch modeli jest następująca:

// Task model 

    var Task = Backbone.RelationalModel.extend({ 

     relations: [ 
      { 
       type: 'HasOne', 
       key: 'user', 
       relatedModel: User 
      } 
     ], 

     urlRoot: 'someUrl' 

    }); 

Potem mam jeden zbiór, który kod wygląda następująco:

var FollowerCollection = Backbone.Collection.extend({ 
    initialize: function() { 
     _.bindAll(this); 
    } 
    model: User 
}); 


var User = Backbone.RelationalModel.extend({ 

}); 

Kiedy robię sprowadzić na FollowerCollection I Uzyskaj następujący błąd:

Uncaught TypeError: Cannot read property 'idAttribute' of undefined 

na linii 1565 z szkieletowy relation.js z backbone-relation version 0.5.0


tu kawałek kodu szkieletowy 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 ]); 

Problem jest związany z _.bindAll(this) ponieważ jeśli Komentuję to, działa poprawnie.
Dlaczego? Jakieś pomysły?


+0

Czy jesteś pewien, że model "Użytkownika" został zdefiniowany podczas deklarowania relacji? –

+0

@mashingan Dołączyłem cały kod o modelu Zadań. możesz rzucić okiem? dzięki. –

+0

Co powiesz na dołączenie kodu dla elementu FollowerCollection i użytkownika, abyśmy mogli spróbować znaleźć problem? Obecnie nie widzę żadnego związku między dwiema klasami. – jakee

Odpowiedz

3

Usunięcie _.bindAll działa.

To wstyd, ponieważ jest to naprawdę przydatna funkcja. Musi źle zetknąć się z częścią szkieletu. Jestem na v9.10

Używam tej metody przez cały czas, a problemy pojawiają się tylko czasami (np. Kiedy chcesz zrobić zbiorczy dodatek do kolekcji).

Dla mnie problem był w tej metodzie 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]; 
}, 

Kod zawiedzie w this.model.prototype ponieważ prototyp jest niezdefiniowany. Co? Tak. Naprawdę.

Problem polega na tym, że po wywołaniu _.bindAll wiąże wszystkie właściwości kolekcji, jak mówi @jakee. Wydaje się, że to obejmuje Collection.model, co jest moim zdaniem problemem.

Rozwiązaniem jest wiązanie poszczególnych metod, dopóki nie zostanie to naprawione.

Istnieje istniejący, ale zamknięty problem na github: https://github.com/documentcloud/backbone/issues/2080 Wygląda na to, że obecni opiekunowie nie lubią tej metody, ale nie rozumiem dlaczego.

0

Podobnie jak mój projekt jest naprawdę duży, musiałem stworzyć swój własny bindAll. Tutaj masz kod, działa z najnowszymi wersjami. Łączę wszystkie właściwości instancji "to", z wyjątkiem tych, które mają prototyp z właściwościami, jak to.model w kolekcji

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

};

Powiązane problemy