2016-09-17 115 views
9

我在Angular web應用中使用AngularFire2。由於Firebase的查詢限制,我無法形成完全提供我需要的數據的查詢(至少不會對我的模式進行重大更改)。如何在客戶端過濾FirebaseListObservable?

所以我想在javascript(typescript)中應用額外的客戶端過濾條件。我該怎麼做呢?我可以以某種方式添加一個過濾器函數給observable?下面是一個說明我在做什麼的片段。

在組件的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」這樣我就可以申請本地(客戶端)過濾器過濾器部件的方法嗎?

回答

7

我遇到了同樣的問題。缺少的部分是過濾陣列本身(Job[]),而不是它周圍的可觀察包裝(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

+0

是的,你是對的。我修正了我的例子。謝謝你的出色答案。 –

2

我還沒有找到真正的可觀察過濾方式,但我發現了一些解決方案。我們可以用* ngFor僞元素過濾元素。所以我的例子變得

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

添加我們添加過濾器()方法來我們的組件代碼:

// 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; 
    } 

我還在尋找一種方式來真正對觀察到的過濾,但同時,這個解決方法是可用的。

+0

我想有使用Observable的原語來做這件事更好。有沒有人有一個例子? –

0

您可以編寫自己的 (類似於對角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>