2012-06-29 30 views
6

Ho due modelli (Utente e Attività) che sono istanze di Backbone.RelationalModel._.bindAll (this) e Uncaught TypeError: Impossibile leggere la proprietà 'idAttribute' di undefined in backbone-relation.js

Il rapporto di questi due modelli è la seguente:

// Task model 

    var Task = Backbone.RelationalModel.extend({ 

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

     urlRoot: 'someUrl' 

    }); 

Poi ho una collezione che il codice è simile al seguente:

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


var User = Backbone.RelationalModel.extend({ 

}); 

quando faccio un'operazione di recupero su FollowerCollection I ottenere il seguente errore:

Uncaught TypeError: Cannot read property 'idAttribute' of undefined 

sulla linea 1565 della spina dorsale-relation.js di backbone-relation version 0.5.0


Ecco un pezzo di codice di 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 ]); 

Il problema è legato alla _.bindAll(this) perché se Lo commento, funziona correttamente.
Perché? Qualche idea?


+0

Sei sicuro che il modello 'Utente' definito quando dichiari la relazione? –

+0

@mashingan Ho allegato tutti i codici relativi al modello Task. puoi dare un'occhiata? Grazie. –

+0

Che ne dici di allegare il codice per FollowerCollection e User in modo che possiamo anche provare a trovare il problema? Attualmente non vedo alcuna relazione tra le due classi. – jakee

risposta

3

La rimozione di _.bindAll funziona.

È un peccato, perché è una funzione molto utile. Deve interagire male con alcune parti di Backbone. Sono su v9.10

Io uso questo metodo tutto il tempo, ed i problemi emergono solo a volte (come quando si vuole fare un grosso carico aggiuntivo a una collezione).

per me, il problema era in questo metodo 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]; 
}, 

Il codice non riesce a this.model.prototype perché prototipo non è definito. Che cosa? Ya. Per i veri.

Il problema è che quando _.bindAll viene chiamato, associa tutte le proprietà della raccolta, come dice @jakee. Questo sembra includere Collection.model, che è un bug credo.

La soluzione consiste nel vincolare i singoli metodi finché non viene risolto.

C'è un ma Chiuso il problema esistente su github: https://github.com/documentcloud/backbone/issues/2080 sembra la manutentori attuali non piace il metodo, ma non capisco perché.

0

Come il mio progetto è davvero grande, ho dovuto creare il mio bind personalizzato. Qui hai il codice, funziona con le ultime versioni. Lego tutte le proprietà dell'istanza "questo" tranne quelle che hanno un prototipo con proprietà, come questa.modello in una raccolta

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

};

Problemi correlati