我在Angular网络应用中使用AngularFire2。由于Firebase的查询限制,我无法形成一个能够提供我所需数据的查询(至少在没有对我的架构进行重大更改的情况下)。
所以我想在javascript(typescript)中应用额外的客户端过滤条件。我该怎么做呢?我可以以某种方式向observable添加过滤函数吗?下面是一个片段,说明了我正在做的事情。
在组件的HTML模板中,我在下面有类似的内容。 "工作" html片段中的变量是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}})
}
有没有办法在&#34; this.jobs&#34;上应用过滤器组件?这样我可以应用本地(客户端)过滤器?
答案 0 :(得分: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
媒体资源属于FirebaseListObservable<Job>
,我认为可观察的类型应为Job[]
vs Job
。
答案 1 :(得分: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的方法,但与此同时,这种解决方法是可用的。
答案 2 :(得分:0)
您可以编写自己的管道 (类似于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>