angular - AngularFirestore 动态查询
问题描述
我正在使用 Angular 9.0.4 和 Firestore 数据库,并且我有一些具有不同位置和主题类别的讲师。这个概念是我将选择我的位置和我想要的主题(例如雅典和数学),我会用这些价值观收回教师。我发现 AngularFire 可以做到这一点,但是我需要的一些“combineLatest”运算符已被弃用,尽管我尝试使用最新的 Rxjs 转换文档代码,但我找不到解决方案。下面是我的代码。
home.component.ts
import {Component, OnInit} from '@angular/core';
import {AngularFirestore} from '@angular/fire/firestore';
import 'firebase/firestore';
import {BehaviorSubject, Observable} from 'rxjs';
import {combineLatest, of} from 'rxjs';
import {map} from 'rxjs/operators';
export interface Instructors {
last_name: string;
location: string;
cate: string;
}
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
instructors$: Observable<Instructors[]>;
locationFilter$: BehaviorSubject<string | null>;
cateFilter$: BehaviorSubject<string | null>;
constructor(afs: AngularFirestore) {
this.locationFilter$ = new BehaviorSubject(null);
this.cateFilter$ = new BehaviorSubject(null);
this.instructors$ = combineLatest(
this.locationFilter$,
this.cateFilter$
).map(([location, cate]) =>
afs.collection<Instructors>('items', ref => {
let query: firebase.firestore.Query = ref;
if (location) {
query = query.where('location', '==', location);
}
if (cate) {
query = query.where('cate', '==', cate);
}
return query;
}).valueChanges()
);
}
ngOnInit() {
}
filterByLocation(location: string | null) {
this.locationFilter$.next(location);
}
filterByCate(cate: string | null) {
this.cateFilter$.next(cate);
}
}
home.component.html
<div *ngIf="instructors$ | async; let instructors; else loading">
<ul>
<li *ngFor="let instructor of instructors">
{{ instructor.last_name }}
</li>
</ul>
<div *ngIf="instructors.length === 0">No results, try clearing filters</div>
</div>
<ng-template #loading>Loading…</ng-template>
<div>
<h4>Filter by</h4>
<div>
<h5>Size</h5>
<button (click)="filterByLocation('Thessaloniki')">Thessaloniki</button>
<button (click)="filterByLocation('Crete')">Crete</button>
<button (click)="filterByLocation(null)" *ngIf="this.locationFilter$.getValue()">
<em>clear filter</em>
</button>
</div>
<div>
<h5>Color</h5>
<button (click)="filterByCate('Leadership')">Leadership</button>
<button (click)="filterByCate('Maths')">Maths</button>
<button (click)="filterByCate(null)" *ngIf="this.cateFilter$.getValue()">
<em>clear filter</em>
</button>
</div>
</div>
firestore 数据库就像
instructors{
randomId{
name: string;
cate: string;
location: string;
}
}
解决方案
您在代码中使用了map
运算符,但您需要订阅新的流,在这种情况下,您需要使用switchMap
运算符。从 RxJS 6.0 开始(如果我没记错的话)你需要使用 pipeable 操作符。
以下代码应该可以工作:
this.instructors$ = combineLatest([this.locationFilter$, this.cateFilter$]).pipe(
switchMap(([location, cate]) =>
afs
.collection<Instructors>('items', ref => {
let query: firebase.firestore.Query = ref;
if (location) {
query = query.where('location', '==', location);
}
if (cate) {
query = query.where('cate', '==', cate);
}
return query;
})
.valueChanges()
)
);
注意:您也可以使用mergeMap
andflatMap
代替switchMap
. 您可以在此处阅读有关它们的更多信息以及它们之间的区别。
推荐阅读
- php - Symfony ManyToOne 删除关系而不更新子实体
- excel - 向包含字母和值的单元格添加值
- java - CosmosDB 记录 appName (mongo API)
- c# - 如何查看 Redis-Commands RESP 表示形式
- stanford-nlp - 如何在 typedDependencies 中保留标点符号?
- javascript - 如何显示最后一个重复值的错误消息
- cors - 如何将 withCredentials 选项传递给 Request?
- angular - 角度为 6 的主布局插座中的嵌套插座
- c# - VS Code (Mac) 缺少灯泡?
- python - 将列表中的值与列表中的字典值进行比较