1

Imagine I would have a component which should receive events, a "player" for instance. The user will likely want to trigger an event to the player, such as "play" or "pause". In my understanding, the @inputs are basically a value we send to the component (and not an event). What is the good practice to trigger those events to the component ?

Considering a player example: - The player has no UI, it's only a tag able to load a source file. - We need to find a convenient way to drive this player firing events such as "start", "stop", "pause"…

I thought about passing an eventEmitter in parameter such as <player [controls]=controls src="somefile.mp3"/> where the control would be the EventEmitter. Then, the component's controller would internally observe this emitter's events and act accordingly (play, stop, pause…).

Any other solution / convention to achieve this ?

More ideas:

  • Create custom specific event on the player's dom element then trigger the event
  • Find a way to get the component's controller within the code and directly call public functions such as play(), pause()…. but then it might be an antipatern with webworkers.
Community
  • 1
  • 1
Flavien Volken
  • 19,196
  • 12
  • 100
  • 133

1 Answers1

0

For a component to respond to received events you can use @HostListener()

@Component({
  ...
})
class SomePlayer {
  @HostListener('play', ['$event'])
  onPlay(event) {
    ...
  }
}

If you use the Renderer like shown in in Angular2 how to know when ANY form input field lost focus to dispatch an event it will work fine with WebWorkers.

You can also use

@HostListener('window:play', ['$event'])

to listen to these events globally.

I'm not sure this is the best solution for your situation. This only listens to events that are fired inside of SomePlayer. Only DOM events are bubbling, while events emitted from EventEmitter are not.

One way would be to use a template variable to be able to reference the player directly from the control and call methods on the MyPlayer component directly.

<player-control (play)="player.play()" (stop)="player.stop()"></player-control>
<my-player #player><my-player>

You can also use

@ViewChild(MyPlayer) player:MyPlayer;

buttonClickHandler() {
  this.player.play();
}

from the component class that has <my-player> in its template.

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567