2016-12-29 6 views
0

Angular2/Firebase/AngularFireを使用してセーリングクラブのソーシャルプラットフォームを構築しようとしています。最初のモジュールは、ユーザーがいくつかの基準(フィルター)でクラブ会員を検索できるようにすることです(最大約10名程度)。 これは、Firebaseのクエリ機能が不足していることを克服するための手法をたくさん探す必要があることを意味していました。 フィルタを管理するコンポーネントを作成しました。子プロセスは、正常にフィルタリングされたメンバーのリストを保持するコンポーネントを持ち、最終的にはクリックハンドラを使用してメンバープロファイル自体にルーティングします。 フィルタコンポーネントは次のとおりです。 HTMLテンプレートには、すべてのフィルタの選択肢にいくつかのラジオが含まれています(例:gender)。これをクリックすると、onFilterメソッドが起動します。AngularFire2 FirebaseList複数の(経路指定された)コンポーネントにわたって観測可能

フィルタコンポーネント

<div class="radio"> 
    <label> 
    <input type="radio" name="genderRadios" id="genderRadioM" value="genderMale" (click)="onFilter('crewGender', 'M')"> 
      Male 
    </label> 
</div> 

これは次いで「crewService」サービスへの呼び出しが新しい値でフィルタアレイを更新することを可能にするonFilter方法

constructor(private crewService: CrewService) {} 

onFilter(myType, myParam) { 
    this.crewFilter = this.crewService.updateFilter(myType, myParam); 
} 

あります。

これは、これを処理するcrewServiceから抽出されたものです。すべてのフィルタ値のペア:

Firebaseサービスハンドラ(CrewService)

updateFilter(myType, myParam){ 
    this.crewFilter[myType] = myParam; 
    return this.crewFilter; 
} 

あなたはcrewFilter配列は、単にキーのリストを保持していることがわかります。次に、CrewServiceサービスはフィルタ配列を取り、それを呼び出すAngularFireリストに対するフィルタとして使用し、最終的にFireBaseListObservableとして生成するメソッドを実装します。これまでのところ、これまでのところ、とても良い。これにより、Firebaseのリストがすべてのフィルタに従って正常にフィルタリングされます(Aは無視されます)。コンポーネントテンプレートではリストを表示し、標準のngForループを使用して解析します。

リストコンポーネント

<div *ngFor="let crew of crews | async; let i = index" class="crewsummary row"> 

このため、TSファイルが含まれています

constructor(private crewService: CrewService) { } 

ngOnInit() { 
    this.crews = this.crewService.getCrews(); 
    this.crewFilter = this.crewService.getFilter(); 
} 

をだから私はローカル '乗組員' オブジェクトを移入しcrewServiceを呼び出すこと。このコンポーネント内

私も(したがって、ボタンをクリックすると、フィルタに無視される「A」、にフィルタを設定し、手段すべて)フィルタをキャンセルするボタンを作成しました:再び

<a *ngIf="crewFilter['crewGender'] == 'M'" class="btn btn-primary" (click)="onFilter('crewGender', 'A')">gender: <b>Male</b> <i class="fa fa-fw fa-times"></i></a> 
<a *ngIf="crewFilter['crewGender'] == 'F'" class="btn btn-primary" (click)="onFilter('crewGender', 'A')">gender: <b>Female</b> <i class="fa fa-fw fa-times"></i></a> 

TSと:メンバーリストは、このコンポーネントから生成されているので、私はリストコンポーネントの内部onFilter()を実行したときに

onFilter(myType, myParam) { 
    this.crewFilter = this.crewService.updateFilter(myType, myParam); 
    this.crews = this.crewService.getCrews(); 
} 

、それが適切にリストを更新し、私は右の結果を得ます。

ここが楽しいところです。

フィルタコンポーネント内の最初の場所にフィルタを適用すると、サービスを再実行してフィルタを適用することができますが、リストコンポーネントにデータが取り込まれることはありません。

リストコンポーネントに強制的にCrewService.getCrews()メソッドが実行され、リストの新しいバージョンが作成されたことを知る方法を見つけることができませんでした。

オブザーバブルやサブスクリプションなどの検索や試行に長時間を要したため、フィルターを適用したときにクルーズオブジェクトの変更を正常に「購読」することができません。

これは誰にとっても意味があるかどうか、合理的に簡単な解決策があるかどうか、または私がウサギの穴を掘り下げたかどうかを知ることはできません。もう一度考えて。

感謝の気持ちで助けてください!

トニー

答えて

2

をありがとうあなたは、フィルタのために観察を使用した場合、あなたは、最新のフィルタを備えた最新のデータベースのリストを組み合わせた観測可能に構成することができます。

import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 
import 'rxjs/add/operator/combineLatest'; 

@Injectable() 
export class CrewService { 

    private crewFilter:any[] = []; 
    private crewFilterSubject = new BehaviorSubject(this.crewFilter); 

    constructor(private af: AngularFire) { 
    this.crews = this.af.database 
     .list('/crew') 
     .combineLatest(this.crewFilterSubject, (items, filter) => { 
     const filtered = items.filter(item => { 
      let match:boolean = true; 
      for (let i in filter) { 
      if(filter[i] !== 'A') { 
       if (item[i] !== filter[i]) match = false; 
      } 
      } 
      return match; 
     }); 
     return filtered; 
     }) as FirebaseListObservable<any[]>; 
    } 

    updateFilter(myType, myParam){ 
    this.crewFilter[myType] = myParam; 
    this.crewFilterSubject.next(this.crewFilter); 
    return this.crewFilter; 
    } 

    getCrews() { 
    return this.crews; 
    } 

あなたはその後、観測可能で構成される、一つだけを必要とする:あなたはこのように、BehaviorSubjectを使用することができるように

フィルタは、初期値を持っています。だからあなたはコンストラクタでそれを作成することができます。

+0

天才!これまでにありがとうございました!完璧に動作します。また、コンストラクタに移動すると、はるかに良く感じられます。受け入れられたとマークした、あなたは私に多くの時間と痛みを救った、もう一度ありがとう!!! –

関連する問題