2017-03-06 91 views
1

我對RxJS(使用5.1.1)非常陌生,並試圖在使用angular-redux/store的Angular 2應用程序中理解它。Angular 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>; 

現在,我m試圖從這個可觀測數據中獲得濾波數組:

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 }}

這將返回:[ { "name": "core", "loaded": true } ] null

+0

你能展示模板部分嗎?當您嘗試將兩個互相引用的對象轉換爲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

在JSON輸出,你可以看到它看起來如下:

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

所以appParts$實際上是發射物體(Observable<AppPart[]>)的陣列,而不是僅僅對象(Observable<AppPart>)。

然後,當您使用this.appParts$.filter(a => a.loaded)時,您試圖通過.loaded篩選項目,該項目不存在於Array對象中,因此它始終爲空。

事實上,你想過濾該數組內的對象。換句話說,你需要將數組拼成單個項目。這意味着我們希望把這樣的:

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

到這一點:

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

這是什麼mergeAll()運營商可以做。在這種情況下使用mergeAll()與使用merge(array => Observable.from(array))相同。

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

現在,當你與.filter(a => a.loaded) IT連鎖你過濾AppPart對象。

請注意,使用async過濾器時,它會訂閱Observable並始終呈現只有最後一個項目從源發出

您可以使用toArray()再次收集經過濾項到一個數組:

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

這有一個重要的後果。 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));這會返回一個Observable ,就像appParts $一樣。 – AppSum