Как ждать, пока наблюдаемые в шаблоне (используя асинхронный канал) будут подписаны, прежде чем запускать код инициализации?

У меня есть служба HTTP, которая возвращает некоторую информацию, когда ему передается заданный идентификатор элемента. Это делается через Subjectкоторый получил первый кусок данных в то время ngOnInit метод.

Затем я использую async Канал для отображения данных, возвращаемых сервисом в HTML.

Моя проблема в том, что async Труба не подписался на наблюдаемые в точке, где я звоню selections.next с первым идентификатором элемента - поэтому этот не отображается при инициализации.

Как я могу ждать, пока async Труба подписалась на Observable прежде чем я отправлю первый кусок данных субъекту, чтобы начать первый HTTP-запрос?

Я пробовал разные хуки жизненного цикла, но ни один из них не работал.

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;
  }
}

1 ответ

Решение

Используйте предмет поведения вместо предмета.

субъект поведения сохраняет свое последнее значение и отправляет его новым подписчикам при подписке.

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-вызов - это субъект вашего поведения, на который вы подписываетесь в шаблоне.

Другие вопросы по тегам