两个使用相同 Observable 的 angular2 服务

Posted

技术标签:

【中文标题】两个使用相同 Observable 的 angular2 服务【英文标题】:Two angular2 services using same Observable 【发布时间】:2017-06-27 11:18:42 【问题描述】:

我有两个 angular2 服务,一个提供数据

@Injectable()
export class DataService 

constructor(private http: Http)  

public getData(): Observable<Data> 
    return this.http.get('/api/foo')
        .map(res => new Data(res.json().data));

还有一个提供设置

@Injectable()
export class SettingsService 

constructor(private http: Http)  

public getSettings(): Observable<Settings> 
    return this.http.get('/api/foo')
        .map(res => new Settings(res.json().settings));

/api/foo 的响应是


    "settings": 
        ...
    
    "data": 
        ....
    

这些服务都使用相同的 api 调用来获取其内容,并且对服务器的调用针对相同的数据进行了两次。

我意识到现有的 api 在将数据和设置组合在一条消息中并不理想,最终可能需要更换。

与此同时,我的问题是:使用现有的 api 是否有一种直接的方法来提供共享相同 api 调用的数据服务和设置服务?是否可以一次调用 api 将数据传递给两个服务,或者每个服务必须独立运行?

更新: 到目前为止,我的想法是我需要创建一个进行实际 http 调用的基本服务,称为 FooService。然后需要将 FooService 注入到 SettingsService 和 DataService 中,然后它们可以将 FooService 的输出分别表示为设置和数据。我遇到困难的地方是如何将 FooService 返回的 Observable&lt;any&gt; 分叉到另外两个 Observables 中,Dataservice 中的 Observeable&lt;Data&gt; 和 SettingsService 中的 Observeable&lt;Settings&gt;?这甚至可能吗?

【问题讨论】:

【参考方案1】:

看起来您想要一种通过按键从对象中动态选择的方法。这是你要找的吗?

public getSettings(dataKey): Observable<Settings> 
    return this.http.get('/api/foo')
        .map(res => new Settings(res.json()[dataKey]);

【讨论】:

@'Simon H' - 代码目前工作正常,响应中有设置和数据属性,不需要动态选择。我的问题是关于如何重构设计,以便只进行一次 http 调用来获取数据,但使用该数据提供两项服务。【参考方案2】:

我想出了如何做到这一点。创建一个服务来访问 api,然后在 api 服务上使用 .map() 创建 Settings 和 Data 服务。

首先创建访问底层api的服务:

@Injectable()
export class ApiService 

    constructor(private http: Http)  

    public getObservable(): Observable<any> 
        return this.http.get('/api/foo')
            .map(res => res.json()));

然后创建程序将使用的两个服务:

@Injectable()
export class SettingsService 

    constructor(private api: ApiService)  

    public getSettings(): Observable<Settings> 
        return this.api.getObservable()
            .map(res => new Settings(res.settings));
    

@Injectable()
export class DataService 

    constructor(private api: ApiService)  

    public getData(): Observable<Data> 
        return this.api.getObservable()
            .map(res => new Data(res.data));
    

【讨论】:

以上是关于两个使用相同 Observable 的 angular2 服务的主要内容,如果未能解决你的问题,请参考以下文章

使用 Observable 的两个同步 http 调用

RxSwift,依赖链的下载返回相同的 Observable 类型

如何在Android中压缩两个Observable?

将Observable的Observable转换为简单的Observable

如何在 Angular/RxJS 中合并两个 observable?

BehaviorSubject vs Observable?