Angular 4 emitting and subscribing to an event in a shared service

坚强是说给别人听的谎言 提交于 2019-12-05 08:53:44

Update: Plunker example no longer maintained please use StackBlitz example here https://stackblitz.com/edit/stackoverflow-questions-45351598-angular?file=src%2Fapp%2Fapp.component.ts

I have created a working plunker example using the code you provided above. 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 {}

View lifecycle hooks here https://angular.io/guide/lifecycle-hooks

Try this:

export class SharedService {
    private dataPusher = new Subject<any>();
    cartData = dataPusher.asObservable().pipe(shareReplay(1));

    pushData(value:any) {
       this.dataPusher.next(value);
    }
} 

What that does is that it will replay the last emitted value for the "late" subscriber. If you want to have a initial value being emitted, you could use BehaviourSubject - it takes initial value in the constructor.

Or you could pipe/chain it with startWith operator.

cartData = dataPusher.asObservable().pipe(startWith("someValue"), shareReplay(1));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!