将普通变量转换为 Observable

Convert normal variable to Observable

我有这个服务:

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

以上代码完美运行。我想要的是当我修改 saveTrailerAndTruck 内的 this.currentTruckTrailer 时,订阅者应该自动更改它们的值。目前我正在使用 public ReplaySubject truckTrailerModified$: ReplaySubject<any>; 广播订阅。问题是如何将 this.currentTruckTrailer 变成 Observable 以便听众可以直接订阅它。我需要在 saveTrailerAndTruckgetCurrentTruckAndTrailer.

内部进行哪些更改

您可以使用 BehaviorSubject (documentation):

首先,你要初始化它:

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

当您想存储数据的下一个值时,可以使用next():

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

当您订阅此 Observable 时,您将收到最后一个存储值(如果存在),并且您的订阅者每次致电 next() 时都会接到电话 next()

编辑: 这是您的服务中的示例实现。由于我不知道上下文以及您希望如何使用此服务,因此这可能不是您可以获得的最佳实现。此示例的目的是向您展示如何实现它。

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