【问题标题】:how to filter an Observable array?如何过滤 Observable 数组?
【发布时间】: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”

标签: typescript firebase firebase-realtime-database observable angularfire


【解决方案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 过滤器方法过滤掉任何空或空数组。
    猜你喜欢
    • 2016-12-31
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2015-08-27
    相关资源
    最近更新 更多