7

Sono curioso di scoprire perché reimpostare una raccolta backbone non attiva un evento modello. Tuttavia, sembra logico attivare un evento modello solo quando un modello viene fisicamente rimosso da una raccolta.Backbone - Perché un insieme.reset non attiva un evento del modello?

È intenzionale o mi manca qualcosa? Se la dorsale non fa questo genere di cose, è una buona pratica per delegare eventi come questo.

Perché il backbone non attiva un evento del modello quando la sua raccolta viene ripristinata?

var TicketModel = Backbone.Model.extend({ 
    defaults: { 
     name: 'crafty', 
     email: '[email protected]' 
    }, 
    initialize: function(){ 
     this.on("all", function(event){ 
      console.log(event) 
     }); 
    } 

}); 

var TicketCollection = Backbone.Collection.extend({ 
    model: TicketModel, 

    }); 


var tickets = new TicketCollection([ 
    { 
     name: 'halldwq' 
    }, 
    { 
     name: 'dascwq' 
    }, 
    { 
     name: 'dsacwqe' 
    } 

]); 

tickets.reset(); 
+0

abbastanza giusto, se questo lo rende più chiaro, grazie rimian – nimrod

risposta

16

L'override del metodo Backbone può causare dolore durante l'aggiornamento a un'altra versione.

Backbone memorizza una vasta gamma di modelli prima del reset nel options.previousModels, quindi basta ascoltare l'evento di reset e innescare un evento di 'rimozione' su quei modelli precedenti:

collection.on('reset', function(col, opts){ 
    _.each(opts.previousModels, function(model){ 
     model.trigger('remove'); 
    }); 
}); 

Che avrebbe fatto il trucco.

16

Questa è la funzione di reset spina dorsale:

reset: function(models, options) { 
    models || (models = []); 
    options || (options = {}); 
    for (var i = 0, l = this.models.length; i < l; i++) { 
    this._removeReference(this.models[i]); 
    } 
    this._reset(); 
    this.add(models, _.extend({silent: true}, options)); 
    if (!options.silent) this.trigger('reset', this, options); 
    return this; 
}, 

possiamo ignorare le ultime 3 righe perché non si fornisce alcun modelli per il reset funzione. Ignoriamo anche le prime 2 linee. Quindi primo ciclo che attraverso i modelli di questa collezione e chiamare il metodo della collezione _removeReference(model), sembra che questo:

_removeReference: function(model) { 
    if (this == model.collection) { 
    delete model.collection; 
    } 
    model.off('all', this._onModelEvent, this); 
}, 

Quello che succede qui è che stiamo rimuovendo la raccolta-proprietà dal modello a oggetti del tutto e anche rimuovere il legame con gli eventi di questo modello. Next up chiamiamo _reset() -funzione della collezione, che assomiglia a questo:

_reset: function(options) { 
    this.length = 0; 
    this.models = []; 
    this._byId = {}; 
    this._byCid = {}; 
}, 

Rimuove solo a titolo definitivo ogni riferimento ad eventuali modelli della collezione abbia mai avuto.

Cosa possiamo ricavarne? Bene, la collezione reset -function in Backbone fondamentalmente elude tutti i canali ufficiali di rimozione dei modelli e fa tutto nel silenzio segreto, causando la mancata attivazione di altri eventi oltre allo reset. Quindi vuoi licenziare l'evento remove del modello per ogni modello rimosso da una collezione durante il reset? Facile! Basta sovrascrivere ripristino funzione di Backbone.Collection come questo:

var Collection = Backbone.Collection.extend({ 
    reset: function(models, options) { 
    models || (models = []); 
    options || (options = {}); 

    for (var i = 0, l = this.models.length; i < l; i++) { 
     this._removeReference(this.models[i]); 
     // trigger the remove event for the model manually 
     this.models[i].trigger('remove', this.models[i], this); 
    } 

    this._reset(); 
    this.add(models, _.extend({silent: true}, options)); 
    if (!options.silent) this.trigger('reset', this, options); 
    return this; 
    } 
}); 

Spero che questo aiuti!

+0

risposta molto approfondita. E anche piacevole da leggere! Molte grazie! – nimrod

+0

nessun problema, è sempre una grande esperienza di apprendimento passare attraverso il codice sorgente per trovare una soluzione per una domanda come questa! – jakee

+0

Mi chiedo quale sia il ragionamento che sta dietro. Un evento "rimuovi" bolle fino alla raccolta, quindi perché non viceversa? – nimrod

Problemi correlati