2016-05-02 15 views
13

TypeScriptでAngular2で書かれたWebアプリケーションでは、RxJs Observableを使用する必要があります。
以前はrxjsを使ったことがなかったので、私は一般的にリアクティブプログラミングに取り掛かっていませんでした。時には、いくつかの特定のことを行う正しい方法を見つけることが困難な場合があります。
私は今問題に直面しています。 Array<Observable<T>>Observable<Array<T>>に変換する必要があります。
私は一例でそれを説明してみましょう:
- User級はObservable<Array<Post>>を返す関数getPostsを持っている - 私は私のUsersObservable<Array<User>>)のリストを与えるObservable
を持っています。
onNext機能内のPostをすべて評価するには、Observable<Array<User>>Observable<Array<Post>>にマップする必要があります。配列に観測可能なRxJs配列

Iは容易私がArray<Post>Array<Array<Post>>を平坦化することができる
map((result : Array<User>) => result.map((user : User) => user.getPosts()))
ANSを用いObservable<Array<Observable<Array<Post>>>>Observable<Array<User>>からマッピングすることができます。
Observable<Array<Observable<Array<Post>>>>Observable<Array<Array<Post>>>
にマップする正しい方法を見つけることができませんでした。今までcombineLatest機能とflatMapを使用しました。
私にはうまくいくように思えましたが、私が使ったエディタ(Atomエディタ)はエラーを表示しませんでした。しかし、今ではNetbeansを使用していますが、このコードではエラーが表示されます。また、 "tsc"を使用してコードをコンパイルすると、エラーが発生します。
次のようになります。

Argument of type '(result: Post[]) => void' is not assignable to parameter of type 'NextObserver<[Observable<Post>]> | ErrorObserver<[Observable<Post>]> | CompletionObserver<[...'. 
Type '(result: Post[]) => void' is not assignable to type '(value: [Observable<Post>]) => void'. 

は、だから私の質問は:
どのように私はArrayObservablesArrayを "フラット化" することができますか?

+0

'getPosts'メソッドは何に対応していますか?特定のユーザーの投稿を読み込みますか? –

答えて

22

flatMapオペレータはこれを実行できます。あなたはすべての

getPostsPerUser() { 
    return this.http.get('/users') 
    .map(res => res.json()) 
    .flatMap((result : Array<User>) => { 
     return Observable.forkJoin(
     result.map((user : User) => user.getPosts()); 
    }); 
} 

Observable.forkJoinあなたが持っているすべての観測を待つことができますをロードしたい場合は...

を私は完全にあなたがやろうか理解していないが、私は答えを提供しようとするでしょう受信したデータ。

上記のコードはuser.getPosts()は、これにより、観察...

を返し、あなたはポストの配列の配列を受け取ることを前提としています

this.getPostsPerUser().subscribe(result => { 
    var postsUser1 = result[0]; 
    var postsUser2 = result[1]; 
    (...) 
}); 
+1

しかし、 'getPosts()'は 'Observable >'を返します。だから私はそれが私が探していることを推測する。私はそれをできるだけ早く試してみて、それがうまくいくかどうかを知らせます。ありがとう – Springrbua

+0

完璧に動作します。私は 'combinedLatest'を' forkJoin'に置き換えるだけの帽子です。どうもありがとう! – Springrbua

3

あなたは関数がrxjs方法に適用する使用することができます

const source1 = Rx.Observable.interval(100) 
 
    .map(function (i) { return 'First: ' + i; }); 
 

 
const source2 = Rx.Observable.interval(150) 
 
    .map(function (i) { return 'Second: ' + i; }); 
 

 
const observablesArray = [source1, source2]; 
 

 
const sources = Rx.Observable.combineLatest 
 
.apply(this, observablesArray).take(4) 
 

 
// or 
 

 
const sources = Rx.Observable 
 
       .combineLatest(...observablesArray) 
 
       .take(4) 
 

 
sources.subscribe(
 
    (response) => { 
 
    console.log(response); 
 
    } 
 
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>

:あなたはこのように、したいです
+0

これはうまくいくはずですが、私は今のところ 'forkJoin'に固執します。 – Springrbua

関連する問題