引用 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();  
  });
}