如何将自定义类型的 AngularFirestoreCollection 传递给 BehaviorSubject?

How do I pass AngularFirestoreCollection of a custom type to BehaviorSubject?

我正在编写一个 angular 应用程序,它使用 firebase/firestore 作为后端数据。我有一个名为“Product”的自定义类型,它有几个属性。在我的 ProductService 中,我有 CRUD 操作。该应用程序将具有用于编辑和删除的对话框组件,因此我在服务中使用了 BehaviorSubject。我遇到的问题是,当我在 BehaviorSubject 中传递 Products 集合时,它无法识别类型。

请参阅下面的代码。在 getAll() 方法中是我的问题所在。当我将 productsRef 应用到 BehaviorSubject (products$) 的下一个方法时,IDE 出现错误:

Argument of type 'AngularFirestoreCollection' is not assignable to parameter of type 'Product[]'.

我遗漏了什么,有什么想法吗?

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Product } from '../models/product.model';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class ProductsService {
  private userId: string;
  products$: BehaviorSubject<Product[]> = new BehaviorSubject([]);
  productsRef: AngularFirestoreCollection<Product>;

  constructor(private afAuth: AuthService, private db: AngularFirestore) {
    this.afAuth.getCurrentUser().then(u => {
      this.userId = u.uid;
      this.products$ = new BehaviorSubject([]);
      this.productsRef = db.collection('products').doc(this.userId).collection('items');         
    });
  }

  getAll(): AngularFirestoreCollection<Product>{
    if(!this.userId) return;
    this.products$.next(this.productsRef);
  }

  create(product: Product): any {
    return this.productsRef.add({...product});
  }

  update(id: string, data: any): Promise<void>{
    return this.productsRef.doc(id).update(data);
  }

  delete(id: string): Promise<void> {
    return this.productsRef.doc(id).delete();
  }
}

因为Array<Product>AngularFirestoreCollection<Product>不是同一种类型。我对 Angular Firestore 不是很有经验,但基本演示看起来利用了从 AngularFirestoreCollection.valueChanges() 返回的可观察对象。因此,您的代码可能如下所示:

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Product } from '../models/product.model';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class ProductsService {
  private userId: string;
  products$: Observable<Product[]>;
  productsRef: AngularFirestoreCollection<Product>;

  constructor(private afAuth: AuthService, private db: AngularFirestore) {
    this.afAuth.getCurrentUser().then(u => {
    this.userId = u.uid;
    this.productsRef = db.collection('products').doc(this.userId).collection('items');         
    this.products$ = this.productsRef.valueChanges();
    });
  }

  create(product: Product) {
    return this.productsRef.add({...product});
  }

  update(id: string, data: any){
    return this.productsRef.doc(id).update(data);
  }
}

然后在您的组件中,您不需要从该服务调用 getAll()。您可以简单地订阅 products$ 并接收新的更新,因为产品是 added/removed。