javascript - traductor - backbone vs react
Backbone: ¿por qué un collection.reset no desencadena un evento modelo? (2)
Tengo curiosidad por saber por qué reiniciar una colección de red troncal no activa un evento modelo. Sin embargo, parece lógico disparar un evento modelo cuando un modelo se elimina físicamente de una colección.
¿Esto es intencional o me estoy perdiendo algo? Si la columna vertebral no hace este tipo de cosas, es una buena práctica para delegar eventos de ese modo.
¿Por qué la red troncal no activa un evento modelo cuando se restablece su colección?
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();
Esta es la función de restablecimiento de la red troncal:
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;
},
Podemos ignorar las últimas 3 líneas porque no suministra ningún modelo a la función de reinicio. También ignoremos las primeras 2 líneas también. Primero revisamos los modelos de esta colección y llamamos al método _removeReference(model)
la colección, se ve así:
_removeReference: function(model) {
if (this == model.collection) {
delete model.collection;
}
model.off(''all'', this._onModelEvent, this);
},
Lo que sucede aquí es que estamos eliminando por completo la propiedad de colección del objeto modelo y también eliminamos el enlace a los eventos de este modelo. A continuación, llamamos a la colección _reset()
-función, que se ve así:
_reset: function(options) {
this.length = 0;
this.models = [];
this._byId = {};
this._byCid = {};
},
Simplemente quita cualquier referencia a cualquier modelo que la colección haya tenido alguna vez.
¿Qué podemos hacer con esto? Bueno, la función de reset
recopilación en Backbone básicamente evita todos los canales oficiales de eliminación de modelos y lo hace todo en silencio, sin causar ningún otro evento que no sea reset
. Entonces, ¿desea activar el evento de remove
del modelo para cada modelo eliminado de una colección durante el reinicio? ¡Fácil! Simplemente sobrescriba Backbone.Collection''s reset-function como este:
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;
}
});
¡Espero que esto ayude!
Anulando el método de Backbone puede causar dolor al actualizar a otra versión.
Backbone almacena una matriz de los modelos antes del restablecimiento en options.previousModels, de modo que solo escuche el evento reset y active un evento ''remove'' en los modelos anteriores:
collection.on(''reset'', function(col, opts){
_.each(opts.previousModels, function(model){
model.trigger(''remove'');
});
});
Eso haría el truco.