首页 文章

rxjs将Observable <List <X >>转换为Observable <X>的运算符

提问于
浏览
0

我'm working with a no-so user-friendly API using Angular HTTP and rxjs. I'我试图从我的服务中返回一个 Observable<List<Object>> . 这里's a sample of the JSON that'从我的get请求中返回:

Items: {
​​    "$type": "System.Collections.Generic.List`1[[Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts]], mscorlib"
​​    "$values": [
       Object { "$type": "Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts", EntityTypeName: "7", Properties: {…} }
       Object { "$type": "Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts", EntityTypeName: "7", Properties: {…} }
       Object { "$type": "Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts", EntityTypeName: "7", Properties: {…} }
    ]
}

然后在每个对象内:

{
  "$type": "Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts"
   EntityTypeName: "7"
   Properties: {
    "$type": "Asi.Soa.Core.DataContracts.GenericPropertyDataCollection, Asi.Contracts"
    "$values": {}
}

我需要为每个项目提取 $values ,然后返回 $values 对象的列表 . 但我想't figure out how to do that with Angular and rxjs without subscribing. And I don'想要订阅,因为我想 component ,而不是 service 来处理结果数据 .

我've been looking in rxjs Operators as a solution to my problem. But there doesn'似乎是一个运算符,它将 List<X> 转换为X,同时保留了Observable .

这可能与Angular2和rxjs有关吗?或者是否有更好的方法来完成这项任务 . 我对反应式编程比较陌生,所以任何一般建议都会受到赞赏 .

2 回答

  • 1

    使用Observable#mergeMap(在其他实现中通常称为 flatMap ) .

    mergeMap 允许您:

    • map 将您的每个项目放入列表中(即,为每个事件发出一个值列表)

    • flatten 列表一起回到一个事件流中


    假设收到以下数据:

    const result = {
      items: {
        $type: 'something something',
        $values: [1, 2, 3]
      }
    }
    

    您可以使用以下方法获取其值的 Observable

    Rx.Observable.of(result).mergeMap(x => x.items.$values)
    

    例如:

    Rx.Observable
      .of(result)
      .mergeMap(x => x.items.$values)
      .subscribe(value => console.log(`new value: ${value}`));
    

    ...打印出来:

    新值:1新值:2新值:3

  • 1

    您可以使用map() - 运算符转换RxJS中的元素 . 它对流中的每个元素应用更改并返回更改的元素 .

    subscribe()的目的是使所有RXJS函数首先被触发 . 因为即使冷可观察量获得新值,也没有任何事情发生,除非在它结束时所有都是订阅 . 所以你可以做到

    const sub = $stream.map(originalValue => {return transformToX(originalValue);})
    .subscribe(transformedValue => {
        emitter.emit(transformedValue);
    });
    

    或者更清楚地证明订阅的目的:

    const sub = $stream.map(originalValue => {return transformToX(originalValue);})
    .do(transformedValue => {
        emitter.emit(transformedValue);
    })
    .subscribe();
    

    当您不再需要时,不要忘记取消订阅所有订阅!请参阅http://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/ .

相关问题