【问题标题】:Bind HTML with AngularFirestore collection via snapshotChanges通过 snapshotChanges 将 HTML 与 AngularFirestore 集合绑定
【发布时间】:2018-04-20 01:00:43
【问题描述】:

我正在使用 AngularFirestore2v5/rxjs 将混合 Ionicv3/Angularv4 移动应用程序连接到 Firestore 集合。我可以在使用 AngularFirestore.valueChanges 时绑定到 UI。切换到 snapshotChanges 来检索 id 给我带来了问题。此线程(和视频)中提供的示例使用地图并登录到控制台。为了让它工作,我还必须在快照 observable 上调用 subscribe。显然它需要一个订阅者才能发出任何东西。后来我发现我可以只使用 subscribe 而无需在它前面加上 map。所以现在我的代码(简化)看起来像:

_col: AngularFirestoreCollection<_model>;
_snapshot: any;

constructor(private afs: AngularFirestore) {
  this._col = this.afs.collection('items'); //items being the name of the collection in firestore
  this._snapshot = this._col.snapshotChanges()
                    .subscribe(actions => {
                      return actions.map(snap => {
                        let id = snap.payload.doc.id;
                        let data = { id, ...snap.payload.doc.data() };
                        console.log(data); //{id: "Q6YZOzyFPvrfsxwT3uTS", field1: "a thing", field2: "another"}
                        return data;
                      });
                    });

订阅中的控制台日志会正确打印存储中的数据。我不知道如何以有角度的方式将其绑定到 UI。

要使 valueChanges 示例正常工作,您必须将异步管道放入 UI。 为 _snapshot 返回这样做:

错误:InvalidPipeArgument:管道“AsyncPipe”的“[object Object]” 尝试仅使用 json 管道会引发:

ERROR TypeError:将循环结构转换为 JSON 这很公平。我知道这不是正确的做法。那是什么?

【问题讨论】:

  • 订阅时不需要异步管道。
  • 这是一个有趣的旁注。谢谢。

标签: angular typescript rxjs ionic3 google-cloud-firestore


【解决方案1】:

异步管道期望一个未订阅的可观察对象并期望返回一个值。异步管道将订阅自己并输出值。

你可以试试

this._snapshot = this._col.snapshotChanges()
                .subscribe(actions => {
                  return actions.map(snap => {
                    let id = snap.payload.doc.id;
                    let data = { id, ...snap.payload.doc.data() };
                    console.log(data); //{id: "Q6YZOzyFPvrfsxwT3uTS", field1: "a thing", field2: "another"}

                    // use data in your html
                    this.data=data

                    return data;
                  });
                });

html

<div *ngFor="let item of data" ....

编辑 1

this.dataArray=this._col.snapshotChanges()
                .map(actions => {
                  return actions.map(snap => {
                    let id = snap.payload.doc.id;
                    let data = { id, ...snap.payload.doc.data() };
                    return data;
                  })
                })

html

<div *ngFor="let item of dataArray | async" ....

【讨论】:

  • 以这种方式将数据分配给公共属性只会公开集合中的最后一项。这是因为 actions.map 单独作用于每条记录。我可以手动将每个分配给一个公共数组并以类似的方式绑定到该数组。但这确实违背了目的。有一种干净的方式将数据从 firestore 绑定到 UI。我就是想不通。
  • 返回的操作类型是什么?它是可观察的吗?
  • Actions 是 DocumentChangeAction[] 的可观察对象,但 subscribe 方法返回订阅类型。
  • 我确定我已经尝试过确切的语法。我一定错过了什么。感谢您抽出宝贵时间。它按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2018-03-19
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
相关资源
最近更新 更多