我正在嘗試爲Angular2/Firebase/AngularFire爲我們的帆船俱樂部構建一個社交平臺。第一個模塊是允許用戶通過幾個標準(過濾器)搜索俱樂部會員,最多可達10個左右。 這本身就意味着我必須搜索大量技術來克服Firebase中缺乏查詢功能。 我創建了一個組件來管理過濾器,使用子路由組件來保存已成功過濾的成員列表,然後最終生成一個單擊處理程序,然後路由到成員配置文件本身。 過濾器組件如下所示: HTML模板包含用於所有過濾器選擇的多個收音機,例如:性別。點擊後,會觸發onFilter方法。跨多個(路由)組件的AngularFire2 FirebaseListObservable
過濾器部件
<div class="radio">
<label>
<input type="radio" name="genderRadios" id="genderRadioM" value="genderMale" (click)="onFilter('crewGender', 'M')">
Male
</label>
</div>
這是則onFilter方法
constructor(private crewService: CrewService) {}
onFilter(myType, myParam) {
this.crewFilter = this.crewService.updateFilter(myType, myParam);
}
這使得一個調用「crewService」服務來更新濾波器陣列用新值。
這是處理此問題的crewService的摘錄。
火力地堡服務處理器(CrewService)
updateFilter(myType, myParam){
this.crewFilter[myType] = myParam;
return this.crewFilter;
}
你可以看到crewFilter陣列只會持有密鑰的列表:所有濾鏡值對。然後CrewService服務實現一個方法,該方法使用過濾器數組並將其用作針對我調用的AngularFire列表的過濾器,並最終將其生成爲FireBaseListObservable。
@Injectable()
export class CrewService {
private crewFilter:any[] = [];
crews:FirebaseListObservable<any[]>;
constructor(private af: AngularFire) {}
getCrews() {
this.crews = this.af.database.list('/crew').map(items => {
const filtered = items.filter(item => {
let match:boolean = true;
for (let i in this.crewFilter) {
if(this.crewFilter[i] !== 'A') {
if (item[i] !== this.crewFilter[i]) match = false;
}
}
return match;
});
return filtered;
}) as FirebaseListObservable<any[]>;
到目前爲止。太好了。根據所有過濾器(忽略A)成功過濾Firebase列表。然後在組件模板中顯示列表,我使用標準的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」,然後在過濾器中被忽略):
<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(myType, myParam) {
this.crewFilter = this.crewService.updateFilter(myType, myParam);
this.crews = this.crewService.getCrews();
}
因爲成員列表是由該組件產生的,當我運行onFilter()列表組件內部,它正確地刷新列表,我得到正確的結果。
這就是樂趣開始的地方!
當我在過濾器組件的第一個地方應用過濾器時,我可以讓服務重新運行crewService.getCrews()來應用過濾器,但它不會被填充到列表組件。
我一直無法找到一種方法來強制列表組件知道CrewService.getCrews()方法已經運行並創建了新版本的列表。
許多小時的搜索和嘗試與觀察和訂閱等相關的事情都失敗了,我不能讓列表組件成功地「訂閱」我在應用過濾器時對工作組對象的更改。 (請注意,數據庫本身所做的更改已成功傳播)
所以我不知道這是否對任何人都有意義,以及是否存在相當簡單的解決方案,或者我是否放棄了兔子洞並需要再想一想。
感謝任何幫助!
謝謝
託尼
天才!真的非常感謝你 !完美的作品。移動到構造函數也感覺好多了。已經標記爲接受,你爲我節省了很多時間和痛苦,再次感謝你! –