使用行为主题 Angular

Using BehavioralSubject Angular

我有 2 个组件和一个服务。服务 class 中的 BehaviorSubject 具有默认值,并且它还从 API 中提取数据。第一个组件获取从 API 中提取的最新数据,但第二个组件仅显示默认值。我的代码可能有什么问题。请指教!

export class WebService {
  public btnsOnResponse; //activates buttons when server responds positive
  BASE_URL = 'http://localhost:3000/api';
  private stats = new BehaviorSubject<IStats>({
    date: this.datePipe.transform(new Date(), 'dd-MM-yyyy'),
    answeringMachine:0,
    hangUp:0,
    conversations:0
  });
  public stats$ = this.stats.asObservable();
  constructor(private http: HttpClient) {
    this.getStatsbyDate('04-03-2018');
  }

组件: 第一个分量

export class StatsComponent {
  public stats: IStats;
  constructor(private webService: WebService, private datePipe: DatePipe) {
    this.webService.stats$.subscribe((data) => {
      if (data !== null) { this.stats = data; } 
      // else { this.webService.stats.next(this.stats); }
      console.log(data);
    })
  }

第二个组件

export class ChartsComponent {
  private stats: IStats;
  constructor(private webService: WebService) {
    this.webService.stats$.subscribe((data: IStats) => {
      this.stats = data;      
    })
    console.log(this.stats);  
  }

您遇到的问题是您正在定义一个 BehaviorSubject 和通过 Observables 管道发送的初始值,但实际上您并没有在收到数据时通过该管道推送下一组值从 API (more reading from RxJS) 返回。这是您更新后的代码示例:

export class WebService {
  public btnsOnResponse; //activates buttons when server responds positive
  BASE_URL = 'http://localhost:3000/api';
  private stats = new BehaviorSubject<IStats>({
    date: this.datePipe.transform(new Date(), 'dd-MM-yyyy'),
    answeringMachine:0,
    hangUp:0,
    conversations:0
  });
  public stats$ = this.stats.asObservable();
  
  constructor(private http: HttpClient) {
    // I am going to assume that the this.getStatsByDate() returns an Observable of some kind.
    this.getStatsbyDate('04-03-2018')
      .subscribe(
        // You needed to subscribe to this function call and then call the .onNext() function in order to pass in the next set of data to your this.stats$ Observable.
        (val: any) => this.stats$.onNext(val)
      );
  }
  
  // I am guessing that you have an implementation of the this.getStatsByDate() function somewhere here, since you didn't include it in your original post.
}

发生这种情况是因为您 运行 另一个 async 操作,正如您在评论中所写 - this.http.get<IStats>。该异步函数有一个回调 - subscribe() 其中包含函数。因为它是 async 而 JavaScript 是 single-threated,所以 Angular 继续构建您的应用程序(组件等),同时该回调被放置在所谓的 "Callback Queue" 中。它仅在调用堆栈(正常 Javascript 函数)为空后触发 - 所以当 Angular 完成构建您的应用程序时(通常)。所以这意味着 this.stats.next(data) 之后 你订阅了你的 BehaviourSubject,所以你得到一个初始值,然后又是另一个。

您可以删除 asyncnext 其他对象:

  constructor(private http: HttpClient) {
    // this.getStatsbyDate('04-03-2018');
    this.stats.next({
      date: this.datePipe.transform(new Date(), 'dd-MM-yyyy'),
      answeringMachine:100,
      hangUp:100,
      conversations:100
    });)
  }

您应该只获取最后一个值。