引用 Angular Firestore 中文档的字段
Referencing a field on document in Angular Firestore
我正在尝试引用 component.ts 文件中文档的字段之一。
只要我明确声明 let day = "Sunday"
.
,下面的代码就可以工作
由于 this.meter 中有一个字段 "day",我希望能够改为声明 let day = this.meter.day
。我知道我必须以某种方式订阅 this.meter
,但我不知道如何订阅。
我已经浏览了所有文档,但我完全不知所措并且非常困惑,因为这应该是一个相对简单的操作。
谢谢。
import { Component, OnInit, ViewChild, ElementRef, HostListener, AfterViewInit } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument, AngularFirestoreCollection, AngularFirestoreCollectionGroup } from '@angular/fire/firestore';
import { Observable, Subscriber } from 'rxjs';
import { ActivatedRoute } from '@angular/router';
export interface Meter { meter: string; units: number; lastupdated: string; year: string; month: string; day: string; monthday: string}
@Component({
selector: 'app-meter',
templateUrl: './meter.component.html',
styleUrls: ['./meter.component.scss']
})
export class MeterComponent implements OnInit {
meterId: string;
private meterDoc: AngularFirestoreDocument<Meter>;
meter: Observable<Meter>;
dailydata: Observable<any>;
todayinweek: Observable<any>;
pastweek: Observable<any>;
day: string;
constructor(
private route: ActivatedRoute, private db: AngularFirestore, private afs:AngularFirestore) {
this.meterId = this.route.snapshot.paramMap.get('id');
this.meter = this.afs.doc<Meter>(`meters/${this.meterId}`).valueChanges();
}
ngOnInit() {
**//let day = this.meter.day;**
let day = "Sunday";
this.dailydata = this.db.collection('meters').doc<any>(this.meterId).collection('dailydata').doc(day).valueChanges();
this.todayinweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.where("day", "==", day).limit(10)).valueChanges();
this.pastweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.orderBy("date", "desc").limit(7)).valueChanges();
}
}
我试过关注 ,但它对我不起作用。我收到一个错误 "Property 'then' does not exist on type 'Observable'"
您可以让每个变量都成为可观察变量,然后让数据流过您的组件:)
首先,您从可观察的路由参数中获取当前 ID,然后使用该 ID 获取仪表 angularfire 集合。
然后从这个 id 结合 meter observable,你可以得到所有其他值。
readonly meterDoc = this.route.paramMap.pipe(
map((params) => params.get('id')),
distinctUntilChanged(),
map((id) => this.db.collection('meters').doc<Meter>(id)),
shareReplay({ refCount: true, bufferSize: 1 })
);
readonly meter = this.meterDoc.pipe(
map((meter) => meter.valueChanges())
);
readonly docMeter = combineLatest([
this.meterDoc,
this.meter
]);
readonly dailydata = this.docMeter.pipe(
switchMap(([ doc, meter ]) => doc.collection('dailydata').doc(meter.day).valueChanges())
);
readonly todayinweek = this.docMeter.pipe(
switchMap(([ doc, meter ]) => doc.collection(
'meterdata',
ref => ref.where("day", "==", meter.day).limit(10)
).valueChanges())
);
readonly pastweek = this.meterDoc.pipe(
switchMap((doc) => doc.collection(
'meterdata',
ref => ref.orderBy("date", "desc").limit(7)
).valueChanges())
);
不过是未经测试的代码
因为您不愿意将所有内容都移动到流中,即使您拥有的所有数据都是异步的。但幸运的是,您还有其他选择。您可以使用路由解析器获取仪表,并在您的组件中阅读:
@Injectable({ providedIn: 'root' })
export class MeterResolve implements Resolve<Meter> {
resolve(route: ActivatedRouteSnapshot): Observable<Meter> {
return this.db.collection('meters')
.doc<Meter>(route.params.id)
.valueChanges()
.pipe(
take(1)
);
}
}
将此添加到您的 id 路线:
{ route: 'meter/:id', component: MeterComponent, resolve: { meter: MeterResolve } }
然后您可以在您的组件中阅读此内容:
readonly meterId = this.route.snapshot.params.id;
readonly meter = this.route.snapshot.data.meter;
readonly meterDoc = this.db.collection('meters').doc<Meter>(this.meterId);
readonly dailydata = this.meterDoc.collection('dailydata').doc(this.meter.day).valueChanges();
readonly todayinweek = this.meterDoc.collection(
'meterdata',
ref => ref.where("day", "==", this.meter.day).limit(10)
).valueChanges();
readonly pastweek = this.meterDoc.collection(
'meterdata',
ref => ref.orderBy("date", "desc").limit(7)
).valueChanges();
如果出于某种原因,你甚至不想使用解析器,你也可以在你的 ngOnInit 中进行订阅,然后从那里开始......但是......请不要:)(这是基于你问题中的代码)
ngOnInit() {
this.meter.pipe(
take(1)
).subscribe(({ day }) => {
this.dailydata = this.db.collection('meters').doc<any>(this.meterId).collection('dailydata').doc(day).valueChanges();
this.todayinweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.where("day", "==", day).limit(10)).valueChanges();
this.pastweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.orderBy("date", "desc").limit(7)).valueChanges();
});
}
我正在尝试引用 component.ts 文件中文档的字段之一。
只要我明确声明 let day = "Sunday"
.
由于 this.meter 中有一个字段 "day",我希望能够改为声明 let day = this.meter.day
。我知道我必须以某种方式订阅 this.meter
,但我不知道如何订阅。
我已经浏览了所有文档,但我完全不知所措并且非常困惑,因为这应该是一个相对简单的操作。
谢谢。
import { Component, OnInit, ViewChild, ElementRef, HostListener, AfterViewInit } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument, AngularFirestoreCollection, AngularFirestoreCollectionGroup } from '@angular/fire/firestore';
import { Observable, Subscriber } from 'rxjs';
import { ActivatedRoute } from '@angular/router';
export interface Meter { meter: string; units: number; lastupdated: string; year: string; month: string; day: string; monthday: string}
@Component({
selector: 'app-meter',
templateUrl: './meter.component.html',
styleUrls: ['./meter.component.scss']
})
export class MeterComponent implements OnInit {
meterId: string;
private meterDoc: AngularFirestoreDocument<Meter>;
meter: Observable<Meter>;
dailydata: Observable<any>;
todayinweek: Observable<any>;
pastweek: Observable<any>;
day: string;
constructor(
private route: ActivatedRoute, private db: AngularFirestore, private afs:AngularFirestore) {
this.meterId = this.route.snapshot.paramMap.get('id');
this.meter = this.afs.doc<Meter>(`meters/${this.meterId}`).valueChanges();
}
ngOnInit() {
**//let day = this.meter.day;**
let day = "Sunday";
this.dailydata = this.db.collection('meters').doc<any>(this.meterId).collection('dailydata').doc(day).valueChanges();
this.todayinweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.where("day", "==", day).limit(10)).valueChanges();
this.pastweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.orderBy("date", "desc").limit(7)).valueChanges();
}
}
我试过关注
您可以让每个变量都成为可观察变量,然后让数据流过您的组件:)
首先,您从可观察的路由参数中获取当前 ID,然后使用该 ID 获取仪表 angularfire 集合。
然后从这个 id 结合 meter observable,你可以得到所有其他值。
readonly meterDoc = this.route.paramMap.pipe(
map((params) => params.get('id')),
distinctUntilChanged(),
map((id) => this.db.collection('meters').doc<Meter>(id)),
shareReplay({ refCount: true, bufferSize: 1 })
);
readonly meter = this.meterDoc.pipe(
map((meter) => meter.valueChanges())
);
readonly docMeter = combineLatest([
this.meterDoc,
this.meter
]);
readonly dailydata = this.docMeter.pipe(
switchMap(([ doc, meter ]) => doc.collection('dailydata').doc(meter.day).valueChanges())
);
readonly todayinweek = this.docMeter.pipe(
switchMap(([ doc, meter ]) => doc.collection(
'meterdata',
ref => ref.where("day", "==", meter.day).limit(10)
).valueChanges())
);
readonly pastweek = this.meterDoc.pipe(
switchMap((doc) => doc.collection(
'meterdata',
ref => ref.orderBy("date", "desc").limit(7)
).valueChanges())
);
不过是未经测试的代码
因为您不愿意将所有内容都移动到流中,即使您拥有的所有数据都是异步的。但幸运的是,您还有其他选择。您可以使用路由解析器获取仪表,并在您的组件中阅读:
@Injectable({ providedIn: 'root' })
export class MeterResolve implements Resolve<Meter> {
resolve(route: ActivatedRouteSnapshot): Observable<Meter> {
return this.db.collection('meters')
.doc<Meter>(route.params.id)
.valueChanges()
.pipe(
take(1)
);
}
}
将此添加到您的 id 路线:
{ route: 'meter/:id', component: MeterComponent, resolve: { meter: MeterResolve } }
然后您可以在您的组件中阅读此内容:
readonly meterId = this.route.snapshot.params.id;
readonly meter = this.route.snapshot.data.meter;
readonly meterDoc = this.db.collection('meters').doc<Meter>(this.meterId);
readonly dailydata = this.meterDoc.collection('dailydata').doc(this.meter.day).valueChanges();
readonly todayinweek = this.meterDoc.collection(
'meterdata',
ref => ref.where("day", "==", this.meter.day).limit(10)
).valueChanges();
readonly pastweek = this.meterDoc.collection(
'meterdata',
ref => ref.orderBy("date", "desc").limit(7)
).valueChanges();
如果出于某种原因,你甚至不想使用解析器,你也可以在你的 ngOnInit 中进行订阅,然后从那里开始......但是......请不要:)(这是基于你问题中的代码)
ngOnInit() {
this.meter.pipe(
take(1)
).subscribe(({ day }) => {
this.dailydata = this.db.collection('meters').doc<any>(this.meterId).collection('dailydata').doc(day).valueChanges();
this.todayinweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.where("day", "==", day).limit(10)).valueChanges();
this.pastweek = this.db.collection('meters').doc<any>(this.meterId).collection(('meterdata'), ref=> ref.orderBy("date", "desc").limit(7)).valueChanges();
});
}