【问题标题】:AngularFire2: Realtime Database: how to get key and valueAngularFire2:实时数据库:如何获取键和值
【发布时间】:2018-03-17 04:23:52
【问题描述】:

我使用 AngularFire2 从 Firebase 数据库(实时)获取数据。

我做了什么:

  • Firebase 数据库

{ “班级” : { “学生” : { “汤姆”:“男性”, “玛丽”:“女性”, “彼得”:“男性”, “劳拉”:“女性” }, “学生人数”:10 } }

  • app.component.ts

    import { AngularFireDatabase } from 'angularfire2/database';
    import { Observable } from 'rxjs/Observable';
    
    ...
    export class AppComponent {
    
       class: Observable<any>;
       students: Observable<any[]>;
    
    constructor(private db: AngularFireDatabase) {
       this.class = db.object(‘class’).valueChanges();
       this.students = db.list(‘class/student’).snapshotChanges();
     }
    
    } 
    
  • app.component.html:

<h2>Class size: {{ (class | async)?.numberOfStudent }}</h2>
<ul>
  <li *ngFor="let i of students | async">
    {{i.key}} : {{i.value}}
  </li>
</ul>

发生了什么:

班级人数:10人

汤姆:

玛丽:

彼得:

劳拉:

它不返回列表的值。

欢迎提出任何建议。

【问题讨论】:

  • 有什么错误吗?为您的键和值做{{ i?.key }} : {{ i?.value }},安全操作员? 将停止任何尚未出现的数据的错误
  • @FussinHussin,没有错误,它使用键,但不是值,只是空值。
  • 你能在你的 .ts 组件中记录这些值吗?数据通过了吗?
  • 数据通过,因为我可以得到密钥。只是不知道我获取值的代码是否正确
  • 是的,但您应该记录数据以确保不会受到伤害

标签: angular firebase angularfire2 real-time-data


【解决方案1】:

我尝试了以上所有这些,但从 Angular 6 开始,这些都不起作用,这对我有用

   const m = this.firestore.collection("class/student").snapshotChanges();
    m.subscribe(res =>{
      console.log(res)
      res.forEach(res => {
        const value = res.payload.doc.data();
        const id = res.payload.doc.id;
        console.log(value," ",id)
      });
    })

很多角火的方法已经过时了。 关键在于 vs 代码建议,将来如果这不起作用,您将不得不类似地探索提供的内容。 暂时

res.payload.doc.data()
res.payload.id

会工作的。

【讨论】:

    【解决方案2】:

    使用 Angular 6
    细分:

    1. 我创建了一个 Map 来存储键/值以供将来查询。

    2. 获取值并将它们添加到之前创建的地图中

    3. 创建了两个辅助方法来分别获取键或值。

    todosKeyValues: Map&lt;string, Todo&gt; = new Map();

    constructor(private databaseFB: AngularFireDatabase) {
        this.fetchKeyValues();
     }
    
    private fetchKeyValues() {
        this.databaseFB.list('/').snapshotChanges().subscribe(actions => {
          actions.forEach(action => {
            const value = action.payload.val();
            const id = action.payload.key;
            this.todosKeyValues.set(id, value);
          });
        });
      }
    
    
     private getKey(id: number): string {
     const foundEntry = Array.from(this.todosKeyValues.entries())
        .filter(entry =>entry[1].id === id).pop();
       return foundEntry ? foundEntry[0] : undefined;
      }
    
      private getTodo(id: number): Todo {
        const foundEntry = Array.from(this.todosKeyValues.entries())
        .filter(entry => entry[1].id === id).pop();
          //index 0 is the key, index 1 is the value
        return foundEntry ? foundEntry[1] : undefined;
      }
      ...
    

    【讨论】:

      【解决方案3】:

      UPD

      使用新的 Angular 6RxJS 6 你可以这样做:

      import { map } from 'rxjs/operators';
      // ...
      return this.fb.list(`/path/to/list`)
        .snapshotChanges()
        .pipe(map(items => { .            // <== new way of chaining
          return items.map(a => {
            const data = a.payload.val();
            const key = a.payload.key;
            return {key, data};           // or {key, ...data} in case data is Obj
          });
        }));
      

      【讨论】:

      • Property 'subscribe' does not exist on type '() =&gt; Observable&lt;{ key: string; }[]&gt;'. 我不能订阅这个回报。有什么想法吗?
      【解决方案4】:

      自@rickdroio 的回答以来,AngularFire2 库已经经历了一些重大变化。以下是解决方案的更新版本:

      afs.collection<Shirt>('class/student').snapshotChanges().map(actions => {
        return actions.map(a => {
          const data = a.payload.val();
          const id = a.payload.id;
          return { id, ...data };
        });
      });
      

      【讨论】:

      • 收到此错误ERROR TypeError: this.fb.list(...).snapshotChanges(...).map is not a function at ... 我认为这是因为 RxJS 6 版本。有人知道怎么解决吗?
      • 见下方回复
      【解决方案5】:

      根据https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md 上提供的指南,您可以这样做:

      afs.collection<Shirt>('class/student').snapshotChanges().map(actions => {
            return actions.map(a => {
              const data = a.payload.doc.data();
              const id = a.payload.doc.id;
              return { id, ...data };
            });
          });
      

      它将返回一个类似于以前的 Firebase db 的数组。

      【讨论】:

        【解决方案6】:

        我设法得到了列表的键和值。只需遵循以下提示:

        • 确保使用 snapshotChanges()

        <li *ngFor="let i of seats | async">
            {{i.key}} : {{i.payload.val()}}
        </li>

        它对我有用,但我仍然愿意接受更多最佳实践

        【讨论】:

          【解决方案7】:

          您的问题是您的 JSON 对象学生不是一个数组,而您正试图循环遍历它。

              "student" : { “Tom” : “male”, “Mary” : “female”, “Peter” : “male”, “Laura” :
          “female” }, "numberOfStudent” : 10 }
          

          你需要让你的学生成为对象列表,以便循环遍历它们,如下所示:

             "student" :
          [ { "name" : "Tom", "sex" : male}, {"name" : "Mary, "sex" : "female" }, ... ]
          

          循环通过let i of student | async 并访问姓名和性别 i?.name, i?.sex

          【讨论】:

          • 我明白你的意思,但是这个 JSON 是从 Firebase 数据库生成的。我使用 AngularFire2 处理数据,而不是通过 JSON 处理数据。
          • 我明白,但您的数据格式化方式是一种不好的做法,最佳做法是将其放入对象格式列表中
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-04
          • 2023-02-02
          相关资源
          最近更新 更多