2017-03-06 81 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