Angulaire 2 Observable avec plusieurs abonnés
J'ai angulaire 2 service d'extraction de données à partir d'une API
ce service dispose de 3 abonnés (défini dans les Composants) chacun de faire autre chose avec les données (graphiques différents)
Je m'aperçois que je suis en train de faire trois demandes pour de l'API, tout ce que je veux réaliser est une demande et que les abonnés pourront partager les données
J'ai regarde dans le CHAUD et le FROID observables et j'ai essayé le .action() sur les observables, mais je suis encore en train de faire 3 appels individuels
Mise à jour, ajout de code
Service
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import {Observable} from 'rxjs/Rx';
//Import RxJs required methods
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { StationCompliance } from './model/StationCompliance';
@Injectable()
export class StationComplianceService {
private url = '/api/read/stations';
constructor(private http : Http) {
console.log('Started Station compliance service');
}
getStationCompliance() : Observable<StationCompliance []> {
return this.http.get(this.url)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server Error'));
}
}
Composante 1
import { Component, OnInit } from '@angular/core';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
import { StationComplianceService } from '../station-compliance.service';
@Component({
selector: 'app-up-down-graph',
templateUrl: './up-down-graph.component.html',
styleUrls: ['./up-down-graph.component.css']
})
export class UpDownGraphComponent implements OnInit {
graphData;
errorMessage: string;
options;
constructor(private stationService : StationComplianceService) { }
ngOnInit() {
this.getStationTypes();
}
getStationTypes(){
this.stationService.getStationCompliance()
.subscribe(
graphData => {
this.graphData = graphData;
this.options = {
chart : {type: 'pie',
plotShadow: true
},
plotOptions : {
showInLegend: true
},
title : {text: 'Up and Down devices'},
series: [{
data: this.processStationType(this.graphData)
}]
}
},
error => this.errorMessage = <any>error
);
}
Deux autres composants sont presque les mêmes, ils ont juste montrer aux autres le graphique
Vous devez vous connecter pour publier un commentaire.
J'ai rencontré un problème similaire et résolu à l'aide d'Aran propose de référence Cory Rylan du Angulaire 2 Données Observables Services blog. Pour moi, l'essentiel a été l'aide de
BehaviorSubject
. Voici les extraits du code qui a finalement fonctionné pour moi.Service De Données:
Le service de données crée un interne
BehaviorSubject
pour mettre en cache les données une seule fois lorsque le service est initialisé. Les consommateurs utilisent lessubscribeToDataService()
méthode d'accès aux données.Composant:
Composants peuvent s'abonner au service de données lors de l'initialisation.
Modèle De Composant:
Le modèle peut ensuite effectuer une itération sur les observables que nécessaire en utilisant la async pipe.
Abonnés sont mis à jour chaque fois que le
next()
méthode est appelée sur leBehaviorSubject
dans le service de données.Le problème que vous avez dans votre code, c'est que vous êtes de retour d'un nouveau observable à chaque fois que votre fonction est appelée. C'est parce que
http.get
est la création d'un nouveau Observable à chaque fois qu'il est appelé. La façon de résoudre ce pourrait être pour stocker les observables (par l'intermédiaire fermeture) dans le service qui va s'assurer que tous les sujets de la souscription de la même observable. Ce n'est pas parfait code, mais j'ai eu un problème similaire et cela a résolu mon problème pour le moment..share()
, car il est crucial pour la question d'éviter le double emploi des appels. La réponse est bonne, si vous voulez éviter des appels asynchrones de la même API point de terminaison. Considérant que, l'on a accepté la réponse peut fournir une réponse en cache même plus que la durée du backend d'appel.vous pouvez créer un réactif de service de données et de définir une variable Observable qui est mis à jour en interne et les abonnés peuvent mettre à jour eux-mêmes.
cet article explique correctement
services de données
La solution est de sauvegarder une fois créé observables et de le rendre partageable (par défaut, elle ne l'est pas). Si votre service ressemblera:
shareReplay
devrait le faire maintenant - "(...) utile dans les situations où vous savez que vous allez avoir la fin d'abonnés à un flux de données qui ont besoin d'accéder à déjà émis des valeurs."Je sais que ce fil est vieux, mais l'on a accepté la réponse m'a beaucoup aidé et je tiens à ajouter quelques améliorations possibles à l'aide d'anti-rebond, switchmap et un hacky mondial de notification système (pour ce faire bonne ngrx doit être utilisée: https://ngrx.io/)
Le principe de ce concept est qu'un service de notification peut être utilisé pour pousser changé pour tous les autres services de leur dire d'aller chercher leurs données:
Un objet est utilisé, en raison de l'appelant .prochaine(val) sur un sujet qui pousse les données à tous les auditeurs
Dans le service pour un particulier composante (dans votre cas, "Susceptible"), vous pouvez gérer les données d'acquisition, et la mise en cache de l'activité:
Le concept clé dans le code ci-dessus, c'est que vous l'installation d'un cache de l'objet, et de le mettre à jour à chaque fois qu'il y a une notification. Dans le constructeur, nous voulons tuyau de toutes les futures notifications par le biais d'une série d'opérateurs:
le service de notification de sorties de certaines choses (dans ce cas "GO"). Si
vous commencez à faire cela, ngrx sera presque certainement être utilisé à la place.
Maintenant, après tout cela, le serveur de données seront placées dans le cache avec le .prochaine(res) de la méthode.
Maintenant, tout le volet final doit faire est d'écouter le cache pour les mises à jour et de gérer l'appropriatly:
Le concept en action:
Angulaire de l'App sur le bouton cliquez sur
Réponse du serveur