如何过滤一个Observable数组?

15

输入图像描述

我的方法从 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);
 }

1
你的 filter 操作符不能正常工作吗? - OJ Kwon
我尝试了,但是出现了这个错误:“[ts]属性'attending'在类型'any[]'上不存在。任何” - Fernando Nicolalde
2个回答

17

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

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为true的项。然后我们过滤掉任何空的或null的数组。

已更新至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)
    );
}

13

你不能使用rxjs的filter方法来完成这个操作,而是要使用从observable接收到的数组对象上的filter方法。

因此,如果你有一个Observable<any[]>,你可以像这样进行筛选:

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

当我在运行时应用第一个选项时,我遇到了“map未定义”的错误,而在第二个选项中,“pipe”没有导出成员。不过问题已经解决了。非常感谢你的帮助。 - Fernando Nicolalde
抱歉,应该在两个选项中都导入地图而不是在第二个选项中导入管道。现已更正。 - Peter Salomonsen
考虑修改以下句子:“你不能使用rxjs过滤方法来实现这个” 在我看来,你应该使用rxjs过滤方法来过滤掉任何空的或null的数组。 - TomerBu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接