2017-03-06 15 views
1

RxJS(5.1.1を使用)では新しく、angle-redux/storeを使用したAngular 2アプリケーションでは理解しています。角度2 RxJSフィルタから新しい観測値へ

私のアプリケーションで私の状態のさまざまな部分を取得するためにストアをセットアップしています。今

、私がtrueに設定されてロードされたプロパティを持つAppPartsを取得しようとしている:

私の状態:

export interface IAppState extends IRootState{ 
    theme: Theme; 
    config: IConfig; 
    mainSubTitle: string; 
    appParts: AppPart[]; 
} 

選択:今

@select(state => state.app.appParts) appParts$: Observable<AppPart>; 

、私は」このオブザーバブルからフィルタリングされた配列を取得しようとしています:

loadedAppParts = []; 

ngOnInit() { 
    this.appParts$.filter(a => a.loaded).subscribe(a => { console.log(a); this.loadedAppParts.push(a); }); 
} 

しかし、これは空の配列を返します。私は、可能な場合には、あまりにも「loadedAppParts」を取得するために非同期パイプを使用できるようにしたいと思いますので、私はまた、次の操作を実行しようとしました:

loadedAppParts: Observable<AppPart> = new Observable<AppPart>(); 
ngOnInit() { 
    this.loadedAppParts = this.appParts$.filter(a => a.loaded); 
} 

だから、どのように私はフィルタ配列や、観察を得ることができます私の観察可能な状態から?

は私Rootstateを追加するのを忘れ:

export interface IRootState { }; 

と私の最初の状態:

export const INITIAL_STATE: IAppState = { 
    theme: THEMES.LightGreyBlue, 
    config: <IConfig>{ 
    data: { 
     apiUrl: '' 
    }, 
    general: { 
     appName: 'Default name', 
     appShortName: 'default' 
    } 
    }, 
    mainSubTitle: 'Default', 
    appParts: [new AppPart('core', true)] 
}; 

そして(配列など)のデバッグにJSONを表示するテンプレートパーツ:

{{ appParts$ | async | json }} {{ loadedAppParts | json }}

Observableを使用する場合: {{ appParts$ | async | json }} {{ loadedAppParts | async | json }}

これが返されます:あなたは次のように見えます見ることができますJSON出力で[ { "name": "core", "loaded": true } ] null

+0

テンプレート部分も表示できますか?このエラーは、お互いに参照する2つのオブジェクトをJSONに変換しようとしたときに発生します。私はあなたがしたいとは思わないJSONに変換します。配列を使用する場合は – martin

+0

:{{appParts $ |非同期| json}} {{loadedAppParts | json}}; Observableを使用する場合:{{appParts $ |非同期| json}} {{loadedAppParts |非同期| json}};最後のものは[{"name": "core"、 "loaded":true}] nullを返す – AppSum

+0

出力から、 'appParts $'は 'AppPart'オブジェクトの配列を出力しているので、正しいタイプは' Observable '。 'this.loadedAppParts = this.appParts $ .mergeAll()。filter(a => a.loaded);で排出量を平準化しようとすると、'それは役に立ちますか? – martin

答えて

2

を:

[ { "name": "core", "loaded": true } ] null 

のでappParts$だけではなく、オブジェクトのオブジェクトの配列(Observable<AppPart[]>)を放出することです(Observable<AppPart>)。

this.appParts$.filter(a => a.loaded)を使用すると、Arrayオブジェクトに存在しないので、常に空になる.loadedプロパティで項目をフィルタリングしようとしています。

実際には、その配列内のオブジェクトをフィルタリングする必要があります。言い換えれば、配列を単一項目に平坦化する必要があります。この中

[ { "name": "core", "loaded": true }, { "name": "core", "loaded": true }, { "name": "core", "loaded": true } ] 

mergeAll()オペレーターが何ができるかだ

{ "name": "core", "loaded": true } 
{ "name": "core", "loaded": true } 
{ "name": "core", "loaded": true } 

これは、我々はこれを有効にすることを意味します。 mergeAll()を使用する場合は、merge(array => Observable.from(array))と同じです。

今、あなたはあなたが AppPartオブジェクトをフィルタリングしている .filter(a => a.loaded)でそれをチェーンするとき
this.appParts$.mergeAll().filter(a => a.loaded); 

asyncフィルタを使用すると、Observableにサブスクライブし、常にレンダリングする最後の項目だけがソースからを放射したことに注意してください。

あなたは再び、アレイ内に濾過アイテムを収集するためにtoArray()を使用することができます。

this.appParts$.mergeAll().filter(a => a.loaded).toArray(); 

これは、1つの重要な結果を持っています。 toArray()演算子は、Observableソースが完了した後にのみ出力されます(ただし、これはユースケースでは問題ではないかもしれません)。

また、すべてのアイテムを収集したい場合は、scan()演算子を使用して、ソースからのすべての排出についてコレクションを発行することもできます(ただし、この演算子は複数のビュー更新を引き起こす可能性があります)。

this.appParts$.mergeAll().filter(a => a.loaded).scan((acc, item) => { 
    acc.push(item); 
    return acc; 
}, []); 
+0

ありがとう!私もこのコードでそれを修正するようだ:this.loadedAppParts = this.appParts $ .map(appParts => appParts.filter(a => a.loaded)); AppParts $と同様にObservable が返されます。 – AppSum

関連する問題