如何过滤 Observable 数组?

Posted

技术标签:

【中文标题】如何过滤 Observable 数组?【英文标题】:how to filter an Observable array? 【发布时间】:2018-06-27 19:02:41 【问题描述】:

我的方法从 Firebase 返回一个 Observable 数组。我决定在客户端而不是服务器中过滤数据。我的问题是,如果属性“attending = true”,我只想获取数据。非常感谢任何帮助或其他方法。非常感谢。

以下方法从firebase实时数据库中获取数据

userEvents: Observable<any[]>;

getUserEvents(uid: string) 
this.userEvents = this.db.list(this.basePatheventsSaved, ref=> 
 ref.orderByChild('uid').equalTo(uid)).snapshotChanges().map((actions) => 
  return actions.map((a) => 
    const data = a.payload.val();
    const $key = a.payload.key;
    return  $key, ...data ;
  );
);
return this.userEvents;
 

下面的代码用于验证模板中要使用的数据:

 userEvents: Observable<any[]>;
 constructor(public auth: AuthService, private upSvc: FilesServiceService)  
this.userEvents = this.upSvc.getUserEvents(this.auth.currentUserId);
 

【问题讨论】:

呃...filter 运算符不适合您? 我试过了,但我得到了这个错误“[ts] Property 'attending' does not exist on type 'any[]'.any” 【参考方案1】:

您应该能够为此使用mapfilter 运算符,并结合Array.prototype.filter。如果我正确理解了您的数据,它应该是这样的:

import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';

userEvents: Observable<any[]>;

constructor(public auth: AuthService, private upSvc: FilesServiceService)  
  this.userEvents = this.upSvc.getUserEvents(this.auth.currentUserId)
    .map(items => items.filter(item => item.attending))
    .filter(items => items && items.length > 0);

首先,我们将数组过滤到只有attending 为真的项目。 然后我们过滤掉任何空或空数组。

为 RXJS 6 更新:

import  pipe  from 'rxjs'; 
import  map, filter  from 'rxjs/operators';

userEvents: Observable<any[]>;

constructor(public auth: AuthService, private upSvc: FilesServiceService)  
  this.userEvents = this.upSvc.getUserEvents(this.auth.currentUserId)
    .pipe(
      map(items => items.filter(item => item.attending)),
      filter(items => items && items.length > 0)
    );

【讨论】:

【参考方案2】:

您不能为此使用 rxjs 过滤器方法,而是使用从 observable 接收的数组对象上的过滤器方法。

因此,如果您有 Observable&lt;any[]&gt;,您可以像这样过滤它:

import 'rxjs/add/operator/map';

this.userEvents.map( arr =>
           arr.filter( r => r.attending === true )
     )
     .subscribe( results => console.log('Filtered results:', results))

从 rxjs 5.5 开始,您应该直接在 Observable 上使用 .pipe 而不是 .map

 import  map  from 'rxjs/operators';

 this.userEvents.pipe( 
         map(arr =>
           arr.filter( r => r.attending === true )
         )
     )
     .subscribe( results => console.log('Filtered results:', results))

【讨论】:

在运行时应用第一个选项时,我得到错误映射未定义,而第二个“管道”中的“管道”没有导出成员。问题虽然解决了。非常感谢您的帮助 很抱歉应该在两个选项上都导入地图,而不是在第二个选项上导入管道。现已更正。 考虑更改以下句子:“您不能为此使用 rxjs 过滤器方法” IMO 您还应该使用 rxjs 过滤器方法过滤掉任何空或空数组。

以上是关于如何过滤 Observable 数组?的主要内容,如果未能解决你的问题,请参考以下文章

来自数组的 Observable 在 TypeScript 中不起作用

Rx 操作符四

RXJS Observable 数组上的简单过滤器

角度过滤器 Observable 数组

如何让一个 Observable 序列在发射前等待另一个完成?

我可以使用 rxjs 针对 id 的字符串数组过滤 Observable