1

我有一个 HTTP 服务,它在将给定的项目 ID 传递给它时返回一些信息。这是通过 a 完成的Subject,它在 thenngOnInit方法中接收第一条数据。

然后我使用async管道以 HTML 格式显示服务返回的数据。

我的问题是async管道在我使用第一个项目 ID 调用时尚未订阅可观察selections.next对象 - 因此在初始化时不会显示这个。

在我将第一条数据发送给主题以开始第一个 HTTP 请求之前,我如何才能等到async管道订阅?Observable

我尝试了不同的生命周期挂钩,但似乎都没有奏效。

import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";

import { ExampleService } from "./example.service";

import "rxjs/add/operator/switchMap";

@Component({
  template: `
    <div>
      <div *ngFor="let time of times | async">{{ time }}</div>
    </div>
  `,
})
export class ExampleComponent implements OnInit {

  times: Observable<string[]>;

  constructor(
    private exampleService: ExampleService
  ) { }

  ngOnInit() {

    var itemIds = new Subject<number>();

    this.times = itemIds
      .switchMap(itemId => this.exampleService.getData(itemId))
      .map(data => this.calculateTimes(data));

    // Pass an item ID to the subject.
    // This is done periodically as well as
    // on init.
    itemIds.next(10);
  }

  calculateTimes(data: string[]) {
    /*
     * Some processing code.
    */

    return data;
  }
}
4

1 回答 1

4

使用行为主题而不是主题。

行为主体保存它的最后一个值并在订阅时将其发送给新订阅者。

import { BehaviorSubject } from "rxjs/BehaviorSubject";


var itemIds = new BehaviorSubject<number>(null);

行为主体需要用一个值初始化。当您不知道您的价值或您的订阅者是否会先到达时,可以解决这个时间问题。

如果你想避免重复调用,你可以设置一个本地存储模式:

times: BehaviorSubject<string[]> = new BehaviorSubject<string[]>();


var itemIds = new Subject<number>();

itemIds.switchMap(itemId => this.exampleService.getData(itemId))
    .map(data => this.calculateTimes(data)).subscribe(this.times);

这样,您唯一的 http 调用订阅者就是您在模板中订阅的行为主题。

于 2017-10-27T19:32:32.050 回答