web-dev-qa-db-fra.com

Comment obtenir la dernière valeur lors de la souscription à un observable?

J'ai deux composants Angular2 qui doivent partager des données via un service:

@Injectable()
export class SearchService {
  private searchResultSource = new Subject<string>()
  searchResult$ = this.searchResultSource.asObservable()

  setSearchResults(_searchResult: string): void {
    this.searchResultSource.next(_searchResult)
  }
}

Supposons que ComponentA soit rendu et émette un événement via SearchService.setSearchResults. Ensuite, l'utilisateur accède à ComponentB, qui s'abonne également à searchResult$. Cependant, ComponentB n'observera jamais l'événement émis par ComponentA car il n'était pas abonné à searchResult$ à l'époque ComponentA a émis un événement, car il n'existait pas.

Comment puis-je créer un Observable qui émet le dernier événement à chaque nouvel abonné?

29
kdu

BehaviorSubject émet immédiatement la dernière valeur aux nouveaux abonnés:

@Injectable()
export class SearchService {

  private searchResultSource = new BehaviorSubject<string>('');

  setSearchResults(_searchResult: string): void {
      this.searchResultSource.next(_searchResult);
  }
}

ReplaySubject envoie tous les événements précédents aux nouveaux abonnés.

41

Vous pouvez utiliser le ReplaySubject pour toujours obtenir la dernière valeur de l'observateur, quelque chose comme ceci:

@Injectable()
export class SearchService {

  private searchResultSource = new ReplaySubject<string>(1);

  setSearchResults(_searchResult: string): void {
      this.searchResultSource.next(_searchResult);
  }
}

Et abonnez-vous comme d'habitude.
Une version plus avancée exemple peut être trouvée ici: mise en cache des résultats avec le service http angular2

12
tibbus