2012-01-06 7 views
6

Me sigo encontrando con este problema una y otra vez. Tengo una vista con una entrada y quiero configurar y actualizar cosas en cada evento keyUp. El problema es cuando se llama al conjunto, desencadena un evento de cambio que vuelve a representar la vista, lo que hace que la entrada pierda el foco. Entonces, después de que el usuario escribe un carácter, la entrada pierde el foco y ya no puede escribir.La vista de re-rendering hace que la entrada pierda el foco

Otro caso donde esto sucede es cuando el usuario hace clic en una entrada. Quiero agregar una clase al div alrededor de la entrada para que cambie de color. Por supuesto, esto hace que la vista vuelva a reproducirse y la entrada pierda el foco. No puedo simplemente hacer una vista separada para la entrada porque la entrada está dentro del div que quiero volver a renderizar.

Aquí hay un ejemplo simple.

itemView = Backbone.View.extend({ 
events: { 
    "keyup .itemInput": "inputKeyUp" 
} 
initialize: function(){ 
    this.model.view = this; 
    this.bind('change', this.render()); 
    this.render(); 
}, 
render: function(){ 
    $(this.el).html($(ich.itemView(this.model.toJSON()))); 
    return this; 
}, 
inputKeyUp: function(e) { 
    this.model.set({name: $(this.view.el).find('input[type=text]').first().val()}); 
}, 
}); 

Hasta ahora lo he solucionado usando {silent: true} y actualizando las cosas manualmente, pero esto crea un desastre.

Respuesta

3

Básicamente te estás metiendo en una especie de situación de ciclo infinito en la que vinculas tu vista demasiado estrechamente con tu modelo y se retroalimentan entre sí.

Cuando un usuario escribe en una entrada de texto del navegador, ya están "actualizando la vista". La vista ya representa el texto adicional.

Por lo tanto, cuando actualiza el modelo con esos cambios, no necesita la vista para actualizar OTRA VEZ, ya que ya representa el estado actual.

Por lo tanto, en estos casos, realmente desea utilizar "silencioso", ya que solo está sincronizando el modelo con el estado actual de la interfaz de usuario, y no necesita el modelo para informar a la vista para actualizar.

En cuanto a la frecuencia con la que hago esto, estoy sospechando que el cifrado es probablemente excesivo. Es posible que desee hacerlo en blur o, incluso, en algún tipo de acción de "guardar".

En cuanto al otro problema, no estoy seguro de por qué agregar una clase a un elemento provocaría que la vista se vuelva a procesar. ¿Simplemente está haciendo algo como

this.$('input[type="text"]').addClass('active') 

Esto no debe activar el evento de cambio de su modelo y hacer que el procesamiento se vuelva a ejecutar.

Enviar un comentario:

que necesita para obtener más granular a continuación.

En términos de representación, rompa la representación/actualización individual de los elementos de la vista en funciones separadas.

Enlaza los eventos de cambio específicos de la propiedad ("cambiar: nombre") a esas funciones de representación más granulares para que actualicen la parte de la vista que deseas cambiar, pero no actualices la entrada de texto.

itemView = Backbone.View.extend({ 
events: { 
    "keyup .itemInput": "inputKeyUp" 
} 
initialize: function(){ 
    this.model.view = this; 
    this.bind('change:name', this.update_other_stuff()); 
    this.bind('change:selected', this.add_class()); 
    this.render(); 
}, 
update_other_stuff: function(){ 
    this.$('.some_other_thing').html("some desired change"); 
    return this; 
}, 
add_class: function(){ 
    this.$('input[type=text]').first().addClass('active'); 
    return this; 
}, 
render: function(){ 
    $(this.el).html($(ich.itemView(this.model.toJSON()))); 
    return this; 
}, 
inputKeyUp: function(e) { 
    this.model.set({name: $(this.view.el).find('input[type=text]').first().val()}); 
}, 
}); 
+0

Sí, la vista ya tiene el texto que el usuario tipeó, pero quiero hacer otras cosas a la vista según lo que escriben. Cuando hacen clic en una entrada, quiero configurar el modelo como seleccionado, que llama a un evento de cambio que vuelve a mostrar la vista con uno que parece seleccionado, lo que hace que la vista pierda su foco. – Dan

Cuestiones relacionadas