【问题标题】:Filtering Observable with Rxjs使用 Rxjs 过滤 Observable
【发布时间】:2017-11-06 03:48:52
【问题描述】:

我正在尝试获取当前用户的活动作业列表:

jobListRef$: Observable<Job[]>;
...
this.afAuth.authState.take(1).subscribe(data => {
  if (data && data.uid) {
    this.jobListRef$ = this.database.list<Job>('job-list', query => {
         return query.orderByChild("state").equalTo("active");
    })
    .snapshotChanges().map(jobs => {
         return jobs.map(job => {
              const $key = job.payload.key;
              const data = { $key, ...job.payload.val() };
              return data as Job;
         });
    })
    .filter(val =>
         val.map(job => {
              return (job.employer == data.uid || job.employee == data.uid);
         })
    );
  }
});

问题仅从过滤开始。根据官方文档,其参数的正确部分应该返回布尔值,就像我的情况一样。但它仍然会返回整个条目而不过滤它们。

【问题讨论】:

    标签: javascript firebase firebase-realtime-database rxjs angularfire2


    【解决方案1】:

    您正在返回 Array.map 调用的结果,查看它的返回值:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

    看起来您可能想使用map 而不是filter

    .snapshotChanges().map(...)
    .map(val => val.map(job => {
       return (job.employer == data.uid || job.employee == data.uid);
    }));
    

    【讨论】:

    • 恐怕它对我不起作用:我仍然得到相同数量的元素,其中一些完全是空的。由于我正在尝试过滤 List Observable,因此我需要检查的不是 val,而是子项。
    【解决方案2】:

    我相信您想反转映射和过滤运算符。

    .map((jobs: Job[]) =>
      jobs.filter((job: Job) => job.employer === data.uid || job.employee === data.uid )
    );
    

    map 将一个数组转换为另一个数组,filter 减少数组)。

    或者您可以将过滤器链接到执行类型转换的地图上,

    .map(jobs => {
      return jobs.map(job => {
        const $key = job.payload.key;
        const data = { $key, ...job.payload.val() };
        return data as Job;
      })
      .filter(job => job.employer === data.uid || job.employee === data.uid )
    })
    

    【讨论】:

    • 谢谢,这正是我想要的。不知何故,我不能靠自己来解决这个问题。 :D
    【解决方案3】:

    不确定是否理解整个问题,但可能是这样的:

    this.jobListRef$ = this.afAuth.authState
        .filter(data => !!data && !!data.uid)
        .take(1)
        .switchMap(data =>
            this.database.list<Job>('job-list', query => query.orderByChild("state").equalTo("active"))
                .snapshotChanges()
                .map(jobs =>
                    jobs.map(job => {
                        const $key = job.payload.key;
                        const data = { $key, ...job.payload.val() };
                        return data as Job;
                    })
                )
                .map((jobs: Job[]) =>
                    jobs.filter(job => (job.employer == data.uid || job.employee == data.uid))
                )
        );
    

    【讨论】:

    • 是的,你说得对。这一个类似于 Richard Matsen 的答案
    • 是的。我们同时写作。很高兴你找到答案。
    猜你喜欢
    • 2019-01-23
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多