Angular 4发布和订阅共享服务中的事件

时间:2017-07-27 13:01:15

标签: angular subscription eventemitter sharedservices

我在我的主要组件中发出了一个事件:

main.component.ts

this.sharedService.cartData.emit(this.data);

这是我的sharedService.ts

import { Component, Injectable, EventEmitter } from '@angular/core';
export class SharedService {
    cartData = new EventEmitter<any>();
} 

在我的其他(Sub)组件中,我想访问此值,但不知何故,订阅不起作用:

dashboard.ts

private myData: any;

constructor(private sharedService: SharedService) {
    this.sharedService.cartData.subscribe(
        (data: any) => myData = data,
        error => this.errorGettingData = <any>error,
        () => this.aggregateData(this.myData));
}

我错过了什么吗?当我将数据作为Injectable传递时,它工作正常。 在一些REST调用之后发生事件(在主组件中)。

更新

所以问题是在第一次发出事件后创建了子组件。我想在这种情况下最好直接将数据注入subcompnent

2 个答案:

答案 0 :(得分:6)

  

<强>更新   不再保留Plunker示例请使用StackBlitz   这里的例子   https://stackblitz.com/edit/stackoverflow-questions-45351598-angular?file=src%2Fapp%2Fapp.component.ts

我使用您在上面提供的代码创建了一个有效的plunker示例。 https://plnkr.co/edit/LS1uqB?p=preview

import { Component, NgModule, Injectable, EventEmitter, AfterViewInit } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';


@Injectable()
export class SharedService {
    cartData = new EventEmitter<any>();
} 

@Component({
  selector: 'app-app',
  template: `
    <h1>
      Main Component <button (click)="onEvent()">onEvent</button>
    </h1>
    <p>
      <app-dashboard></app-dashboard>
    </p>
  `,
})
export class App implements AfterViewInit {
  data: any = "Shared Data";

  constructor(private sharedService: SharedService) {
  }

  ngAfterViewInit() {
    this.sharedService.cartData.emit("ngAfterViewInit: " + this.data);
  }

  onEvent() {
    this.sharedService.cartData.emit("onEvent: " + this.data);
  }
}

@Component({
  selector: 'app-dashboard',
  template: `
    <h2>
      Dashboard component
    </h2>
    <p>
      {{myData}}
    </p>
  `,
})
export class AppDashboard implements AfterViewInit {
  myData: any;

  constructor(private sharedService: SharedService) {
          this.sharedService.cartData.subscribe(
          (data: any) => {
            console.log(data);
            this.myData = data;
          });
  }

}


@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, AppDashboard ],
  providers: [ SharedService ],
  bootstrap: [ App ]
})
export class AppModule {}

在此处查看生命周期挂钩https://angular.io/guide/lifecycle-hooks

答案 1 :(得分:0)

尝试一下:

ul.menu__list
    each menu in data.menu
        li.menu__item
            a.menu__link(
                href=menu.link,
                title=menu.title
            )=menu.label

这样做是为了重播“晚期”订户的最后发出的值。 如果要发出初始值,可以使用export class SharedService { private dataPusher = new Subject<any>(); cartData = dataPusher.asObservable().pipe(shareReplay(1)); pushData(value:any) { this.dataPusher.next(value); } } -它在构造函数中使用初始值。

或者您可以使用BehaviourSubject运算符通过管道对其进行链接。

startWith