Jeanluca Scaljeri
Jeanluca Scaljeri

Reputation: 29097

Angular: Many components listen to key events - refactor?

In a couple of my angular components I listen to key events

@HostListener('window:keydown', ['$event']) keyInput(event: KeyboardEvent) {
   if (this.isActive) {
      if (event.keyCode === 27) {
         // do something
      }
   }
 }

In this case it is just one key, but I have them with more too

Anyway, I see duplicate code in my project here. So, is this acceptable or should I refactor this ? If so, what would be the preferred way?

Upvotes: 2

Views: 534

Answers (1)

Teddy Sterne
Teddy Sterne

Reputation: 14201

I would create a service that other components can subscribe to when the event occurs. For example:

@Injectable()
public class KeyEventService {
    private keydown$: Observable;

    constructor() {
        this.keydown$ = Observable.fromEvent(window, "keydown");
    }

    public getEscapeKeyListener() {
        return this.keydown$.filter((event: KeyboardEvent) => event.keyCode === 27);
    }
}

This allows you to setup the listener for the event once and then filter it to the appropriate keypress. The public methods return observables that filter on specific keys or multiple keys without having to setup a new observable. Then in your component you would use it like this:

@Component({})
public class MyComponent implements OnInit, OnDestroy {
    private keyListenerSub: Subscription;

    constructor(private keyEventSvc: KeyEventService) { }

    ngOnInit() {
        this.keyListenerSub = this.keyEventSvc.getEscapeKeyListener().subscribe(() => {
            /* respond to keypress */
        });
    }

    ngOnDestroy() {
        this.keyListenerSub.unsubscribe();
    }
}

This allows you to set up the listener only once and then in your components you can just take the appropriate action when the event you want occurs.

Upvotes: 5

Related Questions