AngularFire / Firestore - Return collections 和文档即服务

AngularFire / Firestore - Return collections and documents as a service

我有几个页面引用了 firestore 中的同一个节点,每个页面都从 firestore 节点中提取不同的段。例如,一个摘要页面可能包含专辑名称、日期、流派和图像,而另一个页面可能只包含标题、艺术家和唱片公司。几个问题:

  1. 是否可以将其中一个 firestore 查询转换为服务?
  2. 如果是这样,是否意味着在使用相同服务的不同页面(angular 组件)之间导航时,数据仅被读取一次?
  3. 当通过 observable 在 firestore 中修改数据时,是否仅再次查询 运行? ("return Observable.create(观察者 => {")

我已经尝试过使用以下代码的服务。但是,观察到的问题是在页面刷新时,数据不存在。但是,它会在浏览网站时出现。我相信这是因为我的页面 运行ning 在 observable 被 returned 之前。有没有办法将查询包装为可观察的?

如有任何帮助,我们将不胜感激。

getAlbumData() {
  this.albumDoc = this.afs.doc(`albums/${this.albumId}`);
  this.album = this.albumDoc.snapshotChanges();
  this.album.subscribe((value) => {

    // The returned Data
    const data = value.payload.data();

    // Firebase Reference
    var storage = firebase.storage();

    // If album cover exists
    if (data.project_signature != undefined) {

      // Get the Image URL
      var image = data.album_cover_image;

      // Create an image reference to the storage location
      var imagePathReference = storage.ref().child(image);

      // Get the download URL and set the local variable to the result (url)
      imagePathReference.getDownloadURL().then((url) => {
        this.album_cover = url;
      });
    }
  });
}

当我构建我的可观察对象时,我会尽可能多地使用运算符,直到我得到我想要在 UI 中显示的数据。

您不想在 subscribe 方法中实现太多代码,因为这样做会破坏响应式范例。 相反,将您的数据提取到您的可观察对象中并将其显示在您的模板中。 当您的应用程序获取数据时,不要忘记在您的模板中使用异步管道来显示您的数据。

我会这样做:

// In AlbumService
getAlbumCover(albumId: string) {
    const albumDoc = this.afs.doc(`albums/${albumId}`);
    const album_cover$ = this.albumDoc.snapshotChanges().pipe(
      // get the album data from firestore request
      map(data => {
        return {
          id: data.payload.id,
          ...data.payload.data()
        };
      }),
      // emits data only if it contains a defined project_signature
      filter(album => album.project_signature),
      // prepare the imagePath and get the album cover from the promise
      mergeMap(album => {
        const storage = firebase.storage();
        const image = album.album_cover_image;
        const imagePathReference = storage.ref().child(image);
        return imagePathReference.getDownloadURL();
      })
    );
    return album_cover$;
  }

这样,当您的数据在 firestore 中更新时,您的应用程序会自动获取它,因为您使用的是 observable。

在您的组件中,在从 url 获取相册 ID 后的 onInit() 方法中: this.album_cover$ = this.albumService.getAlbumCover(albumId);

最后,在我的模板中,我会这样做:

<div>{{album_cover$ | async}}</div>