首页 > 解决方案 > 是否可以将可观察数据存储到另一个可观察数据中

问题描述

我试图从下面的 observable 中获取名字数组,其响应来自 API(这里是硬编码)我想将初始数据存储在另一个 observable 中。所以我实现的是:

this.initialData=Observable.of({
      data: [
        {
          firstName: 'steve',
          lastName: 'jobs'
        },
        {
          firstName: 'steve1',
          lastName: 'jobs1'
        }
      ]
    })   .map(res => {
        this.wantToAchieveObs$ = Observable.of(res.data);
        return res.data; 
      })
      .switchMap(dataArray => {
        return from(dataArray);
      })
      .bufferCount(5)
      .map((singleArray: any) => {
        return singleArray.map(_ => _.firstname);
      })

但是我没有从 wantToAchieveObs$ 获得可观察的数据,我不想再次让 API 再次命中相同的数据。这是否可以通过任何其他方式实现,因为我也在尝试在 combineLatest 方法中使用这个 observable。

标签: angularrxjsobservable

解决方案


您可能想要的是在您的服务中使用BehaviorSubject 。这有点取决于你想做什么,但你可以做这样的事情:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
// Your imports might be different if you use angular 6
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/filter';

@Injectable()
export class Service {

    // We use this variable to find out if a request to the backend has already been issued.
    private _hasRequested = false;
    // The behavior subject will keep track of the data
    private _subject: BehaviorSubject<any>;
    // This is the observable with the data. You should not expose the subject directly
    // all you want is to expose an observable.
    private _data$: Observable<any>;

    constructor(private http: HttpClient) {
        // BehaviourSubjects need an initial value. We can use undefined
        this._subject = new BehaviorSubject<any>(undefined);
        // Map the subject into an observable.
        this._data$ = this._subject
            .asObservable()
            // We filter out undefined values as we only want to be notified when there is data
            .filter(data => data !== undefined);
    }

    // This method can be used by users of the service.
    // getData().subscribe() will issue a call to the backend when it is called for
    // the first time.
    getData(): Observable<any> {
        // Check if a backend request has already been issued
        if (!this._hasRequested) {
            // If not, issue a request and change the flag to true, so we don't do this again
            this.refresh();
            this._hasRequested = true;
        }
        // Return the data observable
        return this._data$;
    }

    // In case you need to refresh the data that has been loaded, you
    // can use the refresh method to get a newer value from the backend
    refresh() {
        this.http.get('path/to/data')
        .subscribe(
            response => this._subject.next(response),
            error => this._subject.error(error)
        );
    }

}

推荐阅读