我对RxJS很新(使用5.1.1),并尝试使用angular-redux / store在我的Angular 2 applciation中理解它。
我已经设置了商店,并努力在我的应用程序中获取我的州的不同部分。
现在,我试图将已加载属性设置为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); });
}
但是,这会返回一个空数组。我希望能够使用异步管道来获取“已加载的AppPart”。如果可能的话,我也尝试过以下方法:
loadedAppParts: Observable<AppPart> = new Observable<AppPart>();
ngOnInit() {
this.loadedAppParts = this.appParts$.filter(a => a.loaded);
}
那么,如何从我的Observable状态中获取过滤后的数组或observable?
忘记添加我的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 :(得分:2)
在JSON输出中,您可以看到它如下所示:
[ { "name": "core", "loaded": true } ] null
所以appParts$
实际上是发出对象数组(Observable<AppPart[]>
)而不仅仅是对象(Observable<AppPart>
)。
然后,当您使用this.appParts$.filter(a => a.loaded)
时,您尝试按照.loaded
属性过滤项目,而这些属性并不存在于Array对象中,因此它始终为空。< / p>
实际上,您希望过滤该数组中的对象。换句话说,您需要将数组展平为单个项目。这意味着我们要转此:
[ { "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)
对其进行链接时,您将过滤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;
}, []);