Эта проблема

Недавно я начал работу над небольшим проектом с открытым исходным кодом. Музыкальное приложение Gbedu (в разработке - Gbedu). Я решил использовать angular, потому что в конечном итоге я хотел бы сделать ионный порт.

Поэтому я хотел создать компонент проигрывателя, который будет продолжать воспроизводить музыку независимо от того, где я нахожусь в приложении, для этого, конечно, требовалось инициировать событие воспроизведения в родительском компоненте от дочернего компонента. Но проблема в том, что я заставил музыкальный проигрыватель управлять совершенно другим модулем.

Сервис EventEmitter спешит на помощь

Вот что я сделал. Я создал службу для генерации событий управления музыкальным проигрывателем, чтобы я мог слушать службу из любого места в приложении (хотя в этом случае мне нужно слушать только из родительского компонента).

//music.service.ts
import { EventEmitter } from "@angular/core";
export class Music {
  constructor (public image:string,
    public name:string,
    public artist:string,
    public streamUrl:string) {}
}
export class MusicService {
public songPlayEmitter$: EventEmitter<Music>;
  constructor() {
      this.songPlayEmitter$ = new EventEmitter();
   }
   playSong (song:Music):void {
      this.songPlayEmitter$.emit(song)
   }
}

В приведенном выше коде я создал тип Музыка, чтобы я мог определить все свойства, которые я хочу для своих песен. Затем прямо под ним я создал сам сервис MusicService. Каждый раз, когда я нажимаю кнопку воспроизведения в своих элементах управления, я вызываю метод playSong и передаю ему объект песни, который должен содержать все свойства элемента Music class, этот объект песни затем транслируется / передается всем слушателям, которые теперь могут действовать в соответствии с ним. В этом случае родительский компонент содержит музыкальный проигрыватель, который принимает URL-адрес потоковой передачи и воспроизводит звук оттуда.

Далее идут элементы управления музыкой:

// Inside the html file, i am using a click event on the play button like this
<button (click)="playSong(s)">...
//Where -- s --  is the song object retrieved from looping through the song array passed to the view
//In the component file
import {MusicService,Music} from '../../services/music.service'
constructor (musicService: MusicService) {}
playSong (song:Music) {
 this.musicService.playSong(song)
}

В приведенном выше коде я добавляю службу в свой класс компонента. Я также передаю песню из представления функции в моем файле компонента. Затем эта функция вызывает сервисную функцию playSong, которая, в свою очередь, воспроизводит песню для воспроизведения.

Наконец, в моем родительском компоненте я слушаю и действую соответственно так

import {MusicService,Music} from '../../services/music.service'
constructor (musicService: MusicService) {
musicService.songAdded$.subscribe(item => this.displaySong(item));

}
displaySong (songItm:Music) {
   // play music here with whatever audio you wish to use here
   this.isPlayerVisible = true // The music player controls are hidden first in my case so i display them
}

В родительском компоненте я подписан на musicService и жду воспроизведения песни. Как только воспроизводится новая песня, я беру переданную песню и играю ее, используя свою музыкальную библиотеку.

Вот и все, все готово и можно идти. Наслаждаться :-)

Это приложение теперь доступно на Гбеду.