Angular 2 RxJS 过滤器到新的 observable

Angular 2 RxJS filter to new observable

我是 RxJS 的新手(使用 5.1.1)并试图在我的 Angular 2 应用程序中使用 angular-redux/store.

来理解它

我已经设置了一个商店,并正在努力在我的应用程序中获取我所在州的不同部分。

现在,我正在尝试获取已加载 属性 设置为 true 的 AppPart:

我的状态:

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

select:

@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); });
}

不过,这个returns是一个空数组。如果可能的话,我也希望能够使用异步管道来获取 'loadedAppParts',所以我也尝试了以下操作:

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

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

在 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) 链接它时,您正在过滤 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;
}, []);