In backbone.js, how do I bind a key to a document
I am following the Railscast tutorial for backbone.js, and I wanted to extend the functionality by including keyboard controls. I added the following to my view:
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
In my display template, I have the following:
<a href="#" class="back">Back</a> <%= @entry.get('name') %></td>
If I select the backlink using the tab key, then start getting the random keys that I get in my javascript console. However, if I load the page and don’t select the link and just launch the keys, I don’t get the output in my console.
How to associate an event with a document so that it listens to any keys pressed when the screen loads?
You will need to work around the presentation framework. when you do something like this:
events: 'click .back': 'showListing' 'keyup': 'goBack'
you bind your goBack
function to the goBack
event raised in the container element of your view. (default is the div in which the view is displayed)
instead, if you want to link something outside of your view (which doesn't have its own view! (*) )
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; } });
(*) note , as mentioned above, it is best to do this only if the element you want to anchor does not have its own representation, if you have a representation for the full page (application or something like that), you can link with it the keyboard and just raise the App.trigger('keypressed', e);
event App.trigger('keypressed', e);
, eg.
you can bind this App keypressed
event in your EntryShow keypressed
.
App.bind('keypressed', goBack);
Keep in mind that you have to do something as a pending event or group keystrokes in some situations, since turning on every keystroke that happens in the body can be a big hit on performance. especially in older browsers.
Your events will be bound to your @el
element. To write events to document
, you must roll this yourself:
initialize: -> $(document).on "keyup", @goBack remove: -> $(document).off "keyup", @goBack
Gotta do the trick.