tutorial significado redes react network meaning backbonejs backbone javascript-events backbone.js backbone-events

javascript events - significado - Backbone: evento perdido en re-render



backbone vs react (3)

Aquí hay una solución más simple que no elimina los registros de eventos en primer lugar: jQuery.detach() .

http://jsfiddle.net/ypG8U/1/

this.subView.render().$el.detach().appendTo( this.$el );

Sin embargo, esta variación es probablemente preferible por razones de rendimiento:

http://jsfiddle.net/ypG8U/2/

this.subView.$el.detach(); this.subView.render().$el.appendTo( this.$el ); // or this.$el.append( this.subView.render().el );

Obviamente, se trata de una simplificación que coincide con el ejemplo, donde la subvista es el único contenido del padre. Si ese fuera realmente el caso, podría volver a renderizar la vista secundaria. Si hubiera otro contenido, podrías hacer algo como:

var children = array[]; this.$el.children().detach(); children.push( subView.render().el ); // ... this.$el.append( children );

o

_( this.subViews ).each( function ( subView ) { subView.$el.detach(); } ); // ...

Además, en su código original y repetido en la respuesta de jQuery.html() , un objeto DOM se pasa a jQuery.html() , pero ese método solo está documentado como aceptar cadenas de HTML:

this.$el.html( this.subView.render().el );

Firma documentada para jQuery.html() :

.html( htmlString )

http://api.jquery.com/html/#html2

Tengo Super-View quién está a cargo de renderizar sub-Vistas . Cuando vuelvo a renderizar la supervista, todos los eventos en las subvistas se pierden.

Esto es un ejemplo:

var SubView = Backbone.View.extend({ events: { "click": "click" }, click: function(){ console.log( "click!" ); }, render: function(){ this.$el.html( "click me" ); return this; } }); var Composer = Backbone.View.extend({ initialize: function(){ this.subView = new SubView(); }, render: function(){ this.$el.html( this.subView.render().el ); } }); var composer = new Composer({el: $(''#composer'')}); composer.render();

Cuando hago clic en el botón clic en mí, el evento se desencadena. Si ejecuto composer.render() nuevo, todo se ve bastante igual, pero el evento click ya no se activa.

Verifique el jsFiddle de trabajo .


Cuando haces esto:

this.$el.html( this.subView.render().el );

Estás diciendo esto de manera efectiva:

this.$el.empty(); this.$el.append( this.subView.render().el );

y el empty mata los eventos en todo dentro de this.$el :

Para evitar fugas de memoria, jQuery elimina otras construcciones, como los manejadores de datos y eventos, de los elementos secundarios antes de eliminar los elementos.

Por lo tanto, pierde la llamada de delegate que vincula eventos en this.subView y el SubView#render no los volverá a vincular.

this.subView.delegateEvents() pasar una this.subView.delegateEvents() a this.subView.delegateEvents() en this.$el.html() pero necesita que suceda después de empty() . Podrías hacerlo así:

render: function(){ console.log( "Composer.render" ); this.$el.empty(); this.subView.delegateEvents(); this.$el.append( this.subView.render().el ); return this; }

Demostración: http://jsfiddle.net/ambiguous/57maA/1/

O así:

render: function(){ console.log( "Composer.render" ); this.$el.html( this.subView.render().el ); this.subView.delegateEvents(); return this; }

Demostración: http://jsfiddle.net/ambiguous/4qrRa/

O puede remove y volver a crear el this.subView al renderizar y esquivar el problema de esa manera (pero esto podría causar otros problemas ...).


Cuando se usa $(el).empty() se eliminan todos los elementos secundarios del elemento seleccionado Y se eliminan TODOS los eventos (y datos) que están ligados a cualquier elemento (secundario) dentro del elemento seleccionado ( el ).

Para mantener los eventos vinculados a los elementos secundarios , pero aún eliminar los elementos secundarios, use:

$(el).children().detach(); en lugar de $(.el).empty();

Esto permitirá que su vista se reenvíe exitosamente con los eventos aún encuadernados y funcionando.