javascript jquery backbone.js coffeescript

javascript - El evento de cambio del modelo no se activará al actualizar una matriz.



jquery backbone.js (5)

Usando backbone.js ...

@model.bind ''change'', ()-> console.log ''updated'' addIndex = (index) => array = @model.get(''array'') array.push index @model.set array: array

Esto actualiza el modelo perfectamente pero no activa el evento de cambio. ¿Alguien sabe por qué mirando lo que publiqué?

EDITAR:

Agregué esto y desencadena el evento de cambio:

@model.set test: '''' num = 0 setInterval ()=> num++ @model.set test: num , 3000

Agregué esto y no desencadena el evento de cambio:

@model.set test: [] num = 0 setInterval ()=> console.log ''testupdate'' num++ test = @model.get(''test'') test.push num @model.set test: test , 3000


¡La respuesta de Brian sobre el motivo es asombrosa!

Quería presentar otra forma de obtener lo que desea en lugar de anularlo o clonar la matriz.

Simplemente active manualmente el cambio:

addIndex = (index) => array = @model.get(''array'') array.push index @model.trigger(''change:array'',@model, array)


El problema es que está configurando el valor con el valor existente. Eche un vistazo al código fuente:

http://documentcloud.github.com/backbone/docs/backbone.html#section-33

Cuando llamas a set , tiene una cláusula de guardia para asegurarte de que no estás configurando el mismo valor (para evitar bucles de eventos). En su caso, está obteniendo la matriz, modificándola y configurándola nuevamente, lo que no activará su evento.

Por supuesto, cuando set test: {} , es un elemento nuevo con un nuevo objeto, por lo que se activará de nuevo. Si realmente desea desencadenar el evento, puede establecerlo en nulo, luego establecerlo en un conjunto vacío y luego en el conjunto poblado de nuevo ...


¿Podría considerar usar una colección Backbone en lugar de una matriz, y luego vincularla para cambiar los eventos en esa colección?


Como está configurando el objeto al que se hace referencia, use _.clone() .

test = _.clone @model.get(''test'') test.push num @model.set test: test

Como ya no está utilizando el objeto / matriz referenciado para establecerse a sí mismo, activará el evento de cambio si ha cambiado.


Otra forma de hacerlo, al cambiar objetos o matrices, es desarmar silenciosamente la propiedad antes de establecer el nuevo valor actualizado. Algo como esto:

(function() { var arr, model = new Model(); model.set( "arrayProp", [1, 2, 3] ); arr = model.get( "arrayProp" ); arr.push( 4 ); model.unset( "arrayProp", { silent: true } ); model.set( "arrayProp", arr ); })();

Al configurar silent: true al desactivar el accesorio, el evento de cambio solo se disparará una vez (cuando se llama al método set() y la propiedad se ha actualizado).

No hay realmente una diferencia entre hacer esto o llamar manualmente al evento, es solo una cuestión de preferencia personal.