Angular 2广播事件通知其他组件

时间:2017-07-02 15:22:47

标签: android angular

所以我真的失去了理智。我是Angular 2的新手,我正在努力了解如何让兄弟姐妹的组件在彼此之间进行交流。

我有 n 子组件可以播放音频文件。

目标是在有人启动时停止播放组件。

E.G。 :播放组件1,我在组件2上播放,组件1停止,组件2播放。

我尝试使用共享服务但没有运气,也尝试使用EventEmitter从孩子到父母进行通信,但它无效。 我无法弄清楚如何一次通知所有组件。

注册组件(孩子)

import {Component, Input, Output, EventEmitter} from '@angular/core';
import {Path} from "./data-model";
import {MediaPlugin} from '@ionic-native/media';
import {Platform} from 'ionic-angular';
import {SocialSharing} from '@ionic-native/social-sharing';
import {RegistrationService} from './registration.service';

@Component({
  selector: 'registration',
  template: `
      <div class="reg__name">{{ url.name }}</div>
      <button ion-button color="secondary" item-right clear large (click)="toggle(url.path);">
        <ion-icon [name]="playing ? 'md-square' : 'md-play'"></ion-icon>
      </button>`,
  providers: [
    MediaPlugin,
    SocialSharing,
    RegistrationService
  ]
})

export class RegistrationComponent {

  @Input() url: Path;

  @Input() someonePlaying: boolean = false;

  @Output() onPlayed = new EventEmitter<boolean>();

  playing: boolean = false;

  mediaContainer: any;

  path: string;

  constructor(private media: MediaPlugin,
              private platform: Platform,
              private socialSharing: SocialSharing,
              private service: RegistrationService) {

    this.path = "assets/audio";

    // service.playing.subscribe(val => this.onSomeonePlaying(val));

  }

  ngOnChanges() {
    console.log(this.someonePlaying);
  }

  toggle(filename) {
    this.playing
      ? this.stop()
      : this.play(filename)
  }

  play(fileName) {
    const mp3URL = this.getMediaURL(`${this.path}/${fileName}`);
    this.mediaContainer = this.media.create(mp3URL);

    this.mediaContainer.play();
    this.playing = true;
    this.onPlayed.emit(true);
  }

  stop() {
    this.mediaContainer.stop();
    this.playing = false;
    // this.service.stop();
  }

  share() {
    this.socialSharing.shareViaWhatsApp("Condividi su Whatsapp", "", "");
  }

  onSomeonePlaying(val: boolean) {
    console.log(val);
  }

  getMediaURL(s) {
    let isAndroid = this.platform.is("android");
    return isAndroid ? `/android_asset/www/${s}` : s;
  }


}

打印组件的home.html部分

    <ion-item *ngFor="let url of currentUrls">
  <registration (onPlayed)="onPlayed($event)"
                [(someonePlaying)] = "globalPlaying"
                [url]="url"></registration>
</ion-item>

* home.ts **

import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {Registrations, Registration} from './data-model';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})

export class HomePage {

  path: string;

  urls: Array<any>;

  currentUrls: Array<{name: string, path: string}>;

  globalPlaying: boolean = false;

  constructor(public navCtrl: NavController) {

    this.path = "assets/audio";
    this.urls = Registrations;

    this.currentUrls = [];

    for (let i = 0; i < this.urls.length; i++) {
      this.currentUrls = this.currentUrls.concat(this.urls[i]["paths"]);
    }

  }

  onChange(key) {
    this.currentUrls = this.filter(key);
  }

  onPlayed(val){
    console.log("global playing", val);
    this.globalPlaying = true;
  }

  filter(key) {
    if (!key || key === "all")
      return this.findAll(this.urls);

    return this.findWhere(this.urls, key)["paths"];
  }

  findAll(collection) {
    let array = [];
    for (let i = 0; i < collection.length; i++) {
      array = array.concat(collection[i]["paths"]);
    }

    return array;
  }

  findWhere(collection, key) {
    for (let i = 0; i < collection.length; i++) {
      if (collection[i]["id"] === key)
        return collection[i];
    }
  }

}

2 个答案:

答案 0 :(得分:0)

您应该subscribeEventEmiter来捕捉这些事件。您需要一个EventEmiter的服务:

@Injectable()
export class MyService
{
    myEventEmiter:EventEmiter<void> = new EventEmiter<void>();
}

然后inject服务到您的组件并订阅它以捕获事件:

contsruct(protected myService:MyService){}

ngOnInit()
{
    this.myService.subscribe(
        () => { //An event occurs }
    );
}

另一方面,您应该emit EventEmiter来创建新活动:

this.myService.emit();

答案 1 :(得分:0)

我使用一个事件来通知其他实例隐藏我的日期选择器组件。 请关注 event-broadcasting-in-angular-2

您必须创建一个广播公司和messageEvent。