2012-02-16 10 views
6

? He estado siguiendo junto con un tutorial de Backbone.js de Railscast y quería extender la funcionalidad para incluir el control del teclado. He añadido lo siguiente a mi programa de vista:En backbone.js, ¿cómo puedo vincular una clave al documento

class Raffler.Views.EntryShow extends Backbone.View 
    template: JST['entries/show'] 

    events: 
    'click .back': 'showListing' 
    'keyup': 'goBack' 

    showListing: -> 
    Backbone.history.navigate("/", trigger: true) 

    goBack: (e) -> 
    console.log e.type, e.keyCode 

    render: -> 
    $(@el).html(@template(entry: @model)) 
    this 

En mi plantilla espectáculo que he lo siguiente:

<a href="#" class="back">Back</a> 
<%= @entry.get('name') %></td> 

Si selecciono el acoplamiento de nuevo usando la tecla de tabulación, a continuación, comenzar a golpear claves aleatorias que recibo salida en mi consola de JavaScript. Sin embargo, si cargo la página y no elijo el enlace y solo comienzo a presionar las teclas, no obtengo ningún resultado en mi consola.

¿Cómo vinculo el evento al documento para que escuche las teclas presionadas al cargar la pantalla?

+1

posible duplicado de [backbone.js - filtrando una colección con el valor de una entrada] (http://stackoverflow.com/questions/9244773/backbone-js-filtering-a-collection-with-the-value- from-a-input) –

+0

es la misma funcionalidad pero dudo que se pueda ver como un duplicado, esta persona específicamente pregunta cómo puede trabajar con el alcance de una vista, enlazar un evento de tecla hacia el documento y no hacia un entrada única el documento más probable fuera del alcance de la vista. en su propio ejemplo, se vincula a solo 'keyup', lo que significa que lo vincula al elemento contenedor de su vista, que probablemente no sea toda la página. – Sander

Respuesta

6

Tendrá que trabajar alrededor del alcance de las vistas de la red troncal. cuando estás haciendo algo como esto:

events: 
    'click .back': 'showListing' 
    'keyup': 'goBack' 

va a enlazar su función goBack al evento keyup planteado en su elemento contenedor de la vista. (Por defecto el div en el que se representa la vista)

lugar de hacer eso, si desea unirse a algo fuera de su vista (que no tiene su propio punto de vista! (*))

Raffler.Views.EntryShow = Backbone.View.extend({ 
    template: JST['entries/show'], 

    events: { 
    'click .back': 'showListing' 
    }, 

    initialize: function() { 
    $('body').keyup(this.goBack); 
    }, 

    showListing: function() { 
    Backbone.history.navigate("/", trigger: true); 
    }, 

    goBack: function (e) { 
    console.log e.type, e.keyCode; 
    }, 

    render: function() { 
    $(this.el).html(this.template(entry: @model)); 
    return this; 
    } 

}); 

(*) observación como se indicó anteriormente, lo mejor es hacerlo solo cuando el elemento al que desea enlazar no tiene su propia vista, si tiene una vista para su página completa (una vista de aplicación o algo así eso) podría enlazar la clave allí, y simplemente generar un evento App.trigger('keypressed', e); por ejemplo.

puede entonces, en su vista de EntryShow, vincularse al evento keypressed de esa Aplicación.

App.bind('keypressed', goBack); 

tener en cuenta que usted debe hacer algo como un evento retardado o agrupación teclas presionadas juntas en algunas situaciones, como disparar cada pulsación de tecla que sucede en el cuerpo, puede haber un gran impacto en el rendimiento. especialmente en navegadores más antiguos.

+0

Esto funciona para mí en la carga inicial de una vista. Pero cuando el usuario navega hacia la vista por segunda vez, el enlace se vuelve a aplicar y el método se dispara dos veces en cada evento 'keyup'. – wuliwong

+0

puedes resolverlo de 2 formas, puedes usar un administrador de vistas, como una marioneta de red troncal (o una que escribas por ti mismo) y desvincular el evento presionado por tecla cuando la vista se cierra. O puede dejarlo atado, pero trabaje con algún estado procesado. cuando se vincula al evento presionado por tecla, solo lo hace una vez, compruebe si la clase procesada presionada con la tecla está en el contenedor. si no, únete a él, sino simplemente no lo hagas. (después de encuadernar, tiene que configurar la clase para que la segunda vez que lo visite no se vuelva a unir). – Sander

4

Sus eventos se escalarán a su elemento de vista @el. Para capturar eventos en el document, usted tiene que rodar que usted mismo:

initialize: -> 
    $(document).on "keyup", @goBack 

remove: -> 
    $(document).off "keyup", @goBack 

debe hacer el truco.

+1

Esta respuesta aborda la eliminación de la encuadernación, pero 'remove()' no se llama automáticamente, ¿correcto? Necesita algo que se llame cada vez que un usuario navega fuera de una vista. En su lugar, solo me aseguro de que se eliminen los enlaces anteriores antes de aplicarlos en mi vista actual. Es un poco hacky, pero funciona. – wuliwong

+0

@wuliwong yep No creo que se llame automáticamente a 'remove()'. ¿Qué es lo opuesto a 'initialize' que se llama automáticamente cuando el usuario navega fuera de la vista? No pude encontrar uno en el documento. Alguna solución? –

Cuestiones relacionadas