SteveBl
SteveBl

Reputation: 253

How to handle keypress event properly in Ember js 3.13

I'm new to Ember & I want to catch a global key press event and handle it in my component.

After a lot of web crawling I did it the old fashion way with global window.onkeydown = this.handleKeyPress & at the handleKeyPress function i did some code and call this.movePlayerInDirection but now my 'this' is the window.

onKeyPress(e, comp) {
    let keyCode = e.keyCode;`

    if (keyCode === KEY_LEFT ||
        keyCode === KEY_UP ||
        keyCode === KEY_RIGHT ||
        keyCode === KEY_DOWN) {
        let direction;

        switch(e.keyCode) {
            case KEY_LEFT:
                direction = {x: -1, y: 0}
                break;
            case KEY_RIGHT:
                direction = {x: 1, y: 0}
                break;
            case KEY_UP:
                direction = {x: 0, y: -1}
                break;
            case KEY_DOWN:
                direction = {x: 0, y: 1}
                break;
        }
        this.movePlayerInDirection(direction);
    }
}
  1. Is this the best way to catch this event? (the ember way)

  2. How do i reach the component functions from the window scope?

UPDATE:

Based on the answer below I just added window.onkeydown = this.onKeyPress.bind(this) and it worked

Upvotes: 1

Views: 1316

Answers (3)

Patrick Berkeley
Patrick Berkeley

Reputation: 2286

We wrote ember-key-manager because it provides a cleaner interface than any of the other key-event addons. Specifically, it provides a service so you can inject it anywhere and are not stuck using mixins (which are now deprecated).

Upvotes: 0

Ember Freak
Ember Freak

Reputation: 12872

I prefer to use ember-keyboard addon for this job. This has a very nice explanation for features it offers in the the below link, https://github.com/briarsweetbriar/ember-keyboard

Firs you need to add mixin to your component,

import Ember from 'ember';
import { EKMixin } from 'ember-keyboard';

export default Ember.Component.extend(EKMixin, {
  . . . .
});

and then need to set keyboardActivated property to true. The below code will be called after init method.

activateKeyboard: Ember.on('init', function() {
    this.set('keyboardActivated', true);
  })

You shall import the required event

import { keyPress } from 'ember-keyboard';

onKeyPressHandler: Ember.on(keyPress('Escape'), function() {
        // console.log('escape button pressed');        
    }),

In your case, if you want an event to fire for every keypress, then simply don't provide a keystring to keyUp or keyDown. This can be a handy way to trigger events for large ranges of keys, such as on any alphanumeric keypress. For instance:

import { getCode } from 'ember-keyboard';

triggerOnAlphaNumeric: Ember.on(keyUp(), function(event) {
  if (/^Key\w(?!.)/.test(getCode(event))) {
    ...
  }
})

Upvotes: 0

Lux
Lux

Reputation: 18240

There is no special ember way to do this. However there are addons like ember-keyboard-shortcuts.

However generally using window.addEventListener is not a bad idea. However you need to do two things:

  1. cleanup the listener when the component gets destroyed
  2. bind the event to the function context

For a classic component this could look like this:

Component.extend({
  init() {
    this.boundOnKeyPress = this.onKeyPress.bind(this);
  },
  didInsertElement() {
    window.addEventListener('keypress', this.boundOnKeyPress);
  },
  willDestroy() {
    window.removeEventListener('keypress', this.boundOnKeyPress);
  },
  onKeyPress() {
    ...
  }
})

Upvotes: 2

Related Questions