events backbone.js

events - Backbone.js: change not disparando en model.change()



(2)

Interesante. Hubiera pensado que .set({cas:someArray}) habría disparado un evento de cambio. Como dijiste, no parece, y no puedo disparar con .change() PERO, puedo hacer que los eventos funcionen si solo hago model.trigger(''change'') o model.trigger(''change:attribute'')

Esto le permitiría activar el evento de cambio sin ese hack de atributo aleatorio.

Si alguien pudiera explicar lo que está sucediendo con los eventos, Backbone y este código, eso me ayudaría a aprender algo también ... Aquí hay un código.

Ship = Backbone.Model.extend({ defaults: { name:''titanic'', cas: new Array() }, initialize: function() { this.on(''change:cas'', this.notify, this); this.on(''change'', this.notifyGeneral, this); }, notify: function() { console.log(''cas changed''); }, notifyGeneral: function() { console.log(''general change''); } }); myShip = new Ship(); myShip.set(''cas'',new Array()); // No event fired off myShip.set({cas: [1,2,3]}); // <- Why? Compared to next "Why?", why does this work? // cas changed // general change myArray = new Array(); myArray.push(4,5,6); myShip.set({cas:myArray}); // <- Why? // No event fired off myShip.toJSON(); // Array[3] is definitely there myShip.change(); // No event fired off

La parte interesante que podría ayudarte:

myShip.trigger(''change''); // general change myShip.trigger(''change:cas''); // cas changed

Me parece interesante y espero que esta respuesta también genere una explicación perspicaz en los comentarios que no tengo.

Estoy frente a un problema de "evento de cambio que no se dispara" en Backbone.js = /

Aquí mi vista del modelo de usuario:

window.UserView = Backbone.View.extend({ ... initialize: function() { this.model.on(''destroy'', this.remove, this); this.model.on(''change'', function() { console.log(''foo''); }); }, render: function(selected) { var view = this.template(this.model.toJSON()); $(this.el).html(view); return this; }, transfer: function(e) { var cas = listofcas; var transferTo = Users.getByCid(''c1''); var transferToCas = transferTo.get(''cas''); this.model.set(''cas'', cas); console.log(''current model''); console.log(this.model); //this.model.change(); this.model.trigger("change:cas"); console.log(''trigger change''); transferTo.set(''cas'', transferToCas); console.log(''transferto model''); console.log(transferTo); //transferTo.change(); transferTo.trigger("change:cas"); console.log(''trigger change''); } });

Aquí, el modelo de Usuario:

window.User = Backbone.Model.extend({ urlRoot: $(''#pilote-manager-app'').attr(''data-src''), initialize: function() { this.set(''rand'', 1); this.set(''specialite'', this.get(''sfGuardUser'').specialite); this.set(''name'', this.get(''sfGuardUser'').first_name + '' '' + this.get(''sfGuardUser'').last_name); this.set(''userid'', this.get(''sfGuardUser'').id); this.set(''avatarsrc'', this.get(''sfGuardUser'').avatarsrc); this.set(''cas'', new Array()); if (undefined != this.get(''sfGuardUser'').SignalisationBouclePorteur) { var cas = new Array(); _.each(this.get(''sfGuardUser'').SignalisationBouclePorteur, function(value) { cas.push(value.Signalisation); }); this.set(''cas'', cas); } } });

En el modelo de Usuario, hay un atributo "cas", que es una matriz de objetos.

Leo en otros temas que cambian los eventos no son fuego en model.set si los atributos no son un valor.

Por lo tanto, intento activar directamente el evento de cambio con el método model.change (). Pero no tengo ningún "foo" en mi consola ...


Soy bastante nuevo en la columna vertebral y estaba teniendo el mismo problema.

Después de investigar un poco, encontré algunas publicaciones que arrojaban un poco más de luz sobre por qué sucedía esto y, finalmente, las cosas empezaron a tener sentido:

Pregunta 1

Pregunta 2

La razón central tiene que ver con la noción de igualdad de referencia versus igualdad de conjunto / miembro. Parece que, en gran medida, la igualdad de referencia es una de las principales técnicas que utiliza la red troncal para determinar cuándo ha cambiado un atributo.

Encuentro que si uso técnicas que generan una nueva referencia como Array.slice () o _.clone (), se reconoce el evento de cambio.

Entonces, por ejemplo, el siguiente código no desencadena el evento porque estoy alterando la misma referencia de matriz:

this.collection.each(function (caseFileModel) { var labelArray = caseFileModel.get("labels"); labelArray.push({ Key: 1, DisplayValue: messageData }); caseFileModel.set({ "labels": labelArray }); });

Si bien este código activa el evento:

this.collection.each(function (caseFileModel) { var labelArray = _.clone(caseFileModel.get("labels")); // The clone() call ensures we get a new array reference - a requirement for the change event labelArray.push({ Key: 1, DisplayValue: messageData }); caseFileModel.set({ "labels": labelArray }); });

NOTA: Según la API Underscore , _.clone () copia ciertos elementos anidados por referencia. Sin embargo, el objeto raíz / principal está clonado, por lo que funcionará bien para la red troncal. Es decir, si su matriz es muy simple y no tiene estructuras anidadas, por ejemplo [1, 2, 3].

Si bien mi código mejorado anterior activó el evento de cambio, el siguiente no lo hizo porque mi matriz contenía objetos anidados:

var labelArray = _.clone(this.model.get("labels")); _.each(labelArray, function (label) { label.isSelected = (_.isEqual(label, selectedLabel)); }); this.model.set({ "labels": labelArray });

Ahora, ¿por qué importa esto? Después de la depuración con mucho cuidado, noté que en mi iterador estaba haciendo referencia al mismo objeto que se estaba almacenando la red troncal de referencia. En otras palabras, inadvertidamente había llegado a las entrañas de mi modelo y volteado un poco. Cuando llamé a setLabels (), la red troncal reconoció correctamente que nada había cambiado porque ya sabía que había invertido ese bit.

Después de mirar un poco más, la gente parece decir generalmente que las operaciones de copia profunda en javascript son un verdadero dolor, nada incorporado para hacerlo. Así que hice esto, lo cual funcionó bien para mí: la aplicabilidad general puede variar:

var labelArray = JSON.parse(JSON.stringify(this.model.get("labels"))); _.each(labelArray, function (label) { label.isSelected = (_.isEqual(label, selectedLabel)); }); this.model.set({ "labels": labelArray });