2017-05-19 4 views
0

Ich habe dies in meinem Dienst:auf beobachtbare

import { Injectable, EventEmitter } from '@angular/core' 
import { Response } from '@angular/http' 
import { Observable, ReplaySubject } from 'rxjs/Rx'; 
import { AppSettings, HttpClient } from './shared'; 
import _ from "lodash"; 

@Injectable() 
export class UserService { 

    private currentTruckTrailer: any; 
    private trucksTrailers: any; 
    public truckTrailerModified$: ReplaySubject<any>; 

    constructor(private http: HttpClient) { 
     this.truckTrailerModified$ = new ReplaySubject(1); 

    } 

    clearCache() { 
     this.currentTruckTrailer = null; 
     this.trucksTrailers = null; 
    } 

    login(username: string, password: string, clientID: number): Observable<any> { 
     return this.http.post(`${AppSettings.API_ENDPOINT}/User/Login`, { username: username, password: password, clientID: clientID }).map((response: Response) => { 
      return response.json(); 
     }); 
    } 

    getTrailersAndTrucks(): Observable<any> { 
     if (this.trucksTrailers) { 
      return Observable.of(this.trucksTrailers); 
     } 
     else { 
      return this.http.get(`${AppSettings.API_ENDPOINT}/User/GetTrailersAndTrucks`).map((response: Response) => { 
       if (response.status == 200) { 
        this.trucksTrailers = response.json(); 
        return this.trucksTrailers; 
       } 
       else { 
        return "FAILURE"; 
       } 
      }); 
     } 
    } 

    saveTrailerAndTruck(truckID: string, trailerID: string): Observable<any> { 
     return this.http.post(`${AppSettings.API_ENDPOINT}/User/SaveTrailerAndTruck`, { truckID: truckID, trailerID: trailerID }).map((response: Response) => { 

      var truck = _.find(this.trucksTrailers.Trucks, function (item: any) { 
       return item.ID == truckID; 
      }); 

      var trailer = _.find(this.trucksTrailers.Trailers, function (item: any) { 
       return item.ID == trailerID; 
      }); 

      this.currentTruckTrailer = { Truck: truck, Trailer: trailer }; 

      this.truckTrailerModified$.next(this.currentTruckTrailer); 
      return response.json(); 
     }); 
    } 

    getCurrentTruckAndTrailer() { 
     if (this.currentTruckTrailer) { 
      return Observable.of(this.currentTruckTrailer); 
     } 
     else { 
      return this.http.get(`${AppSettings.API_ENDPOINT}/User/GetCurrentTruckAndTrailer`).map((response: Response) => { 
       if (response.status == 200) { 
        this.currentTruckTrailer = response.json(); 
        return this.currentTruckTrailer; 
       } 
       else { 
        return "FAILURE"; 
       } 
      }); 
     } 
    } 
} 

Der obige Code funktioniert perfekt. Was ich will ist, wenn ich die this.currentTruckTrailer innerhalb saveTrailerAndTruck ändern, sollten die Abonnenten ihre Werte automatisch ändern. Im Moment verwende ich public ReplaySubject truckTrailerModified$: ReplaySubject<any>;, um das Abonnement zu übertragen. Frage ist, wie mache ich die this.currentTruckTrailer in Observable, so dass Hörer direkt abonnieren können. Welche Änderungen müsste ich innerhalb saveTrailerAndTruck und getCurrentTruckAndTrailer machen.

Antwort

1

können Sie verwenden eine BehaviorSubject (documentation):

vor allem Sie es initialisieren müssen:

currentTruckTrailer:BehaviorSubject<any> = new behaviorSubject<any>(); 

Wenn Sie den nächsten Wert Ihrer Daten speichern möchten, können Sie next() verwenden :

this.currentTruckTrailer.next({ Truck: truck, Trailer: trailer }); 

wenn Sie diesen Observable anmelden, erhalten Sie den letzten gespeicherten Wert erhalten, wenn ein solches vorhanden ist, und Ihr Teilnehmer wird jedes Mal angerufen, wenn Sie next() anrufen.

EDIT: Hier ist eine Beispielimplementierung in Ihrem Service. Da ich den Kontext und die Art und Weise, wie Sie diesen Service nutzen möchten, nicht kenne, ist dies wahrscheinlich nicht die beste Implementierung, die Sie erhalten können. Das Ziel dieses Beispiels ist es, Ihnen zu zeigen, wie Sie es implementieren.

import {Injectable} from '@angular/core' 
import {Response} from '@angular/http' 
import {Observable, BehaviorSubject} from 'rxjs/Rx'; 
import {AppSettings, HttpClient} from './shared'; 
import _ from 'lodash'; 

@Injectable() 
export class UserService { 

    private currentTruckTrailer: BehaviorSubject<any> = new BehaviorSubject<any>(); 
    private trucksTrailers: BehaviorSubject<any[]> = new BehaviorSubject<any[]>(); 

    constructor(private http: HttpClient) { 
     //First of all, we initialize the currentTruckTrailer with a value coming from http. 
     this.http.get(`${AppSettings.API_ENDPOINT}/User/GetCurrentTruckAndTrailer`) 
      .subscribe((response: Response) => { 
       this.currentTruckTrailer = new BehaviorSubject<any>(response.json()); 
      }); 

     //Same for truckTrailers. 
     this.http.get(`${AppSettings.API_ENDPOINT}/User/GetTrailersAndTrucks`) 
      .subscribe((response: Response) => { 
       this.trucksTrailers = new BehaviorSubject<any[]>(response.json()); 
      }); 
    } 

    login(username: string, password: string, clientID: number): Observable<any> { 
     return this.http.post(`${AppSettings.API_ENDPOINT}/User/Login`, { 
      username: username, 
      password: password, 
      clientID: clientID 
     }).map((response: Response) => { 
      return response.json(); 
     }); 
    } 

    getTrailersAndTrucks(): Observable<any> { 
     return this.trucksTrailers; 
    } 

    saveTrailerAndTruck(truckID: string, trailerID: string): Observable<any> { 
     return this.http.post(`${AppSettings.API_ENDPOINT}/User/SaveTrailerAndTruck`, { 
      truckID: truckID, 
      trailerID: trailerID 
     }).do(() => { 

      const truck = _.find(this.trucksTrailers.Trucks, function (item: any) { 
       return item.ID == truckID; 
      }); 

      const trailer = _.find(this.trucksTrailers.Trailers, function (item: any) { 
       return item.ID == trailerID; 
      }); 

      this.currentTruckTrailer.next({Truck: truck, Trailer: trailer}); 
     }).map(response => { 
      return response.json(); 
     }); 
    } 

    getCurrentTruckAndTrailer(): Observable<any> { 
     return this.currentTruckTrailer; 
    } 
} 
+0

Vielen Dank. Ich folge nicht, wie man es benutzt. Könnten Sie das bitte in meinem Service ändern? Ich denke, die Methoden zu ändern sind ** saveTrailerAndTruck ** und ** getCurrentTruckAndTrailer ** –

+0

Wenn ich Ihre Bedürfnisse gut verstehe, muss Ihr UserService wie ein Cache für trailersAndTrucks Variable handeln? – Supamiu

+0

@TimLiberty Ich habe die Antwort bearbeitet, aber wenn Sie einen Cache-Service benötigen, kann ich Ihnen ein besseres Beispiel geben, das ich für eines meiner Projekte auf GitHub gemacht habe. – Supamiu