2017-04-07 51 views
2

私は、メッセージのストリームをサブスクライブするサンドボックスを持っています。そのストリームをフィルタリングして、別のコンポーネントで指定されたルートパラメータを使用して特定のユーザーと送受信されたメッセージを探したいとします。RxJS観測可能なマージ角度

messages.sandbox.ts:

messages$: Observable<Array<Message>> = this.store.select(state => state.data.messages);  

fetchReceived(id: string): Observable<Array<Message>> { 
    return this.messages$.map((messages: any) => { 
     return messages.filter((message: Message) => { 
      return message.recipientId == id; 
     }); 

    }); 
} 

fetchSent(id: string): Observable<Array<Message>> { 
    return this.messages$.map((messages: any) => { 
     return messages.filter((message: Message) => { 
      return message.userId == id; 
     }) 
    }) 
} 

messages.detail.container.ts

sentMessages$ = new Observable<Array<Message>>(); 
receivedMessages$ = new Observable<Array<Message>>(); 
matchingMessages$ = new Observable<Array<Message>>(); 



ngOnInit() { 

    this.route.params.subscribe((params: Params) => { 
     this.sentMessages$ = this.sb.fetchReceived(params['id']); 
     this.receivedMessages$ = this.sb.fetchSent(params['id']); 

     this.matchingMessages$ = Observable.merge(this.sentMessages$, this.receivedMessages$); 

    }); 
} 

this.matchingMessages $だけ私はそれを知ってthis.sentMessages this.receivedMessages $が含まれているようですテンプレートで問題なく使用できるので、$はnullではありません。

Observablesのマージで何か不足していますか? userIdまたはrecipientIdのいずれかをフィルタリングする単一のfetchMessagesメソッドを作成する方が良いでしょうか?もしそうなら、私はそれについてどのように行くだろうか?

ありがとうございます!

答えて

0

あなたは適切な一般的な考えがあります。ほんの少しの欠陥。

  1. new Observable<T>()を絶対に使用しないでください。それはあなたが思っていることをしません。それはかなり有用な何もしません。ファクトリメソッドまたは他のオブザーバブルから常にオブザーバブルを構築する
  2. オペレータを使用して、観測可能なパラメータを新しいオブザーバブルに変換する必要があります。あなたの問題はです。params observableにをサブスクライブし、毎回新しいobservablesを構築します。しかし、他のコードは、最初の観測値に既に登録されているので、変更を見ることはありません。

ですから、このような何かやりたい:それは送信側と受信側と一致する単一の観察可能なを作成することをお勧めです:依存したとき、あなたの他の質問に答えるために

sentMessages$ : Observable<Array<Message>>; 
receivedMessages$ : Observable<Array<Message>>; 
matchingMessages$ : Observable<Array<Message>>; 

ngOnInit() { 
    const params$ = this.route.params; 

    // use switchMap to map the new params to a new sent observable 
    // each time params change, unsubscribe from the old fetch and subscribe 
    // to the new fetch. Anyone subscribed to "sentMessages" will see the 
    // change transparently 
    this.sentMessages$ = params$.switchMap((params: Params) => this.sb.fetchReceived(params['id'])); 
    // same for received 
    this.receivedMessages$ = params$.switchMap((params: Params) => this.sb.fetchSent(params['id']))); 

    // merge the 2 streams together 
    this.matchingMessages$ = Observable.merge(this.sentMessages$, this.receivedMessages$); 
} 

編集をあなたのユースケースしかし、ここであなたがそれについて行くことができる方法です:

messages.sandbox.ts:

fetchEither(id: string): Observable<Array<Message>> { 
    return this.messages$.map((messages: any) => { 
     return messages.filter((message: Message) => { 
      return message.recipientId == id || message.userId === id; 
     }); 

    }); 
} 

コンテナ:

matchingMessages$ : Observable<Array<Message>>; 

ngOnInit() { 
    const params$ = this.route.params; 

    // use switchMap to map the new params to a new either observable 
    // each time params change, unsubscribe from the old and subscribe 
    // to the new fetch. Anyone subscribed to "matchingMessages" will see the 
    // change transparently 
    this.matchingMessages$ = params$.switchMap((params: Params) => this.sb.fetchEither(params['id'])); 
} 
+0

おかげでブランドン!答えと説明の両方のため。私はRxjsの新人です。残りのサンドボックスのコードパターンとよく似た2番目のソリューションを使用して終了します –

関連する問題