9

我在 Angular Web 应用程序中使用 AngularFire2。由于 Firebase 的查询限制,我无法形成一个准确地提供我需要的数据的查询(至少在不对我的架构进行重大更改的情况下不会)。

所以我想在javascript(打字稿)中应用一个额外的客户端过滤条件。我该怎么做呢?我可以以某种方式向可观察对象添加过滤器功能吗?下面是一个片段,说明了我在做什么。

在组件的 HTML 模板中,我在下面有类似的内容。html 片段中的“jobs”变量是 FirebaseListObservable。

<tr *ngFor="let job of jobs | async"> 
  .. fill in the table rows

组件代码如下所示:

   // in the member declaration of the class
   jobs : FirebaseListObservable<Job[]>;

   ...
   // Notice in ngOnInit(), I'm filtering the jobs list using the the
   // Firebase criteria. But I want to filter on an additional field. 
   // Firebase allows only single field criteria, so I'm looking for 
   // a way to apply an additional client-side filter to jobs to eliminate
   // some additional records. 

   ngOnInit(){
      this.jobs = this.af.database.list("/jobs/", {query: {orderByChild : "companyKey", equalTo:someKey}})
   }

有没有办法在“this.jobs”上应用过滤器组件,以便我可以应用本地(客户端)过滤器?

4

3 回答 3

9

我遇到了同样的问题。缺少的部分是过滤数组本身(Job[]),而不是围绕它的 Observable 包装器(FirebaseListObservable<Job[]>)。

能够使用 RxJS 运算符做到这一点map

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map'

...

@Component({
  ...
})
export class JobComponent {

  ...

  getJobsLessThanPrice(price: number): Observable<Job[]> {
    return this.af.database.list('jobs', {query: {...}})
      .map(_jobs => _jobs.filter(job => job.price > price));

  }
}

如果job.price > price返回 true,则包含在内。

还注意到您的jobs属性是 type FirebaseListObservable<Job>,我原以为可观察类型应该是Job[]vs Job

于 2016-12-29T13:09:37.357 回答
2

我还没有找到真正过滤 observable 的方法,但我找到了某些情况下的解决方法。可以使用 *ngFor 在元素中进行伪过滤。所以我的例子变成了

<tr *ngFor="let job of jobs | async" [hidden]="filter(job)"> 
  .. fill in the table rows

添加我们将 filter() 方法添加到我们的组件代码中:

// in the member declaration of the class
   jobs : FirebaseListObservable<Job[]>;

   ...

   ngOnInit(){
      this.jobs = this.af.database.list("/jobs/", {query: {orderByChild : "companyKey", equalTo:someKey}})
   }

   filter(job : Job) : boolean{
     // Return true if don't want this job in the results.
     // e.g. lets filter jobs with price < 25;
     if (job.price < 25){
       return true;
     }
     return false; 
  }

我仍在寻找一种真正过滤 observable 的方法,但与此同时,这种解决方法是可用的。

于 2016-09-19T18:23:47.377 回答
1

您可以编写自己的管道 (类似于Angular 1.X 上的过滤器)

import {Pipe, PipeTransform} from '@angular/core';
import * as _ from 'lodash';

@Pipe({
  name: 'search'
})
export class SearchPipe implements PipeTransform {

 transform(value: any, args?: any): any {

  if (args) {
    return _.filter(value, d => _.find(_.valuesIn(d), v => 
        _.toLower(v).indexOf(_.toLower(args)) !== -1));
  }

 return value;
 }
 }   

然后,在组件的模板中使用这个管道:

<input [(ngModel)]="term"> 
<li *ngFor="let item of items | async | search:term">{{item}}</li>
于 2017-09-13T10:34:56.720 回答