【问题标题】:Data fetch from firebase从 Firebase 获取数据
【发布时间】:2018-08-30 11:40:11
【问题描述】:
import { Component } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  courses;

  constructor(db: AngularFireDatabase) {
    db.list('/courses').valueChanges()
      .subscribe(courses => {
        this.courses = courses;
        console.log(this.courses);
      });
  }
}

预期行为: [对象,对象,对象,对象]

实际行为: [“课程 1”、“课程 2”、{...}、{...}]

上面的代码返回一个数组,但我期望的是一个对象数组。同样返回的类型,但 valueChanges() 是 Observable。我想知道它是 valueChanges() 的正常行为,即返回一个 Observable 作为对象以及一个数组。请帮帮我,告诉我我的代码哪里错了。我想要一个对象数组作为此代码的最终结果。

【问题讨论】:

  • 你能告诉我们你的数据库的结构吗?
  • 我想我找到了实际行为的原因。我将 JSON 文件导出到我的编辑器,当我看到它的结构时,它与我预期的有很大不同。就像下面 sn-p: { "courses" : [ null, "course1", "course2", { "author" : "Mosh Hamedani", "price" : 150, "title" : "course3" } ] } 我是 firebase 新手,请告诉我数据应该以面向对象的格式还是上面的格式存储。非常感谢您提供有关数据库的线索。

标签: firebase firebase-realtime-database angularfire2


【解决方案1】:

回答您的问题:是的,这是正常行为。

由于 Firebase 是一个实时数据库,它希望跟踪您查询过的任何路径并查看它是否发生了变化(无论变化来自何处,您或您的用户)

我不确定你想对之后返回的对象做什么,但由于代码非常小,我希望你只需要在一些列表中显示它的值......

所以我会写这样的东西,您仍然可以访问Array 中的每个项目,就像它是object

# course.model.ts
export class courseModel {
    title:  string = "";
    price:  string = "";
    author: string = "";
}

# app.component.ts
import { Component } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  courses : Observable<courseModel[]> = new courseModel();

  constructor(db: AngularFireDatabase) {
      this.courses = db.list('/courses').valueChanges();          
  }
}

# app.html
<p *ngFor="let course of courses | async">
 {{ course.title }}
 {{ course.author }}
 {{ course.price }}
</p>

【讨论】:

    【解决方案2】:

    来自https://github.com/angular/angularfire2/blob/master/docs/rtdb/lists.md

    valueChanges()

    它是什么? - 将 Observable 数据作为 JSON 对象的同步数组返回。所有 Snapshot 元数据都被剥离,只有方法只提供数据。

    所以你得到的是[value],而不是[{ key: value }]

    如果您想要完整的对象,包括密钥,请使用snapshotChanges()
    为此,您还需要从 rxjs/operators 导入 map

    import { map } from "rxjs/operators";
    
    db.list('/courses').snapshotChanges()
      .pipe(map(snapshots => {
        return snapshots.map(snapshot => {
          let course = {};
          course[snapshot.key] = snapshot.payload.val();
          return course;
        });
      })).subscribe(courses => {
        this.courses = courses;
        console.log(this.courses);
      });
    

    这将返回结构为[{ key: value }] 的用户数组。如果您希望它的格式不同,例如 [{ "key": key, "value": value }],请告诉我,我会更新我的答案。

    【讨论】:

    • 使用您的代码,它在地图运算符上显示错误,上面写着“属性'地图'不存在于类型'Observable>[]>'”我已经导入地图运算符也是。
    • import 'rxjs/add/operator/map'; 添加到文件顶部。
    • 是的,我已经用和你一样的方式导入了地图运算符。
    • 也尝试添加import { Observable } from "rxjs/Rx";
    • 现在错误出现在键上的 snapshot.key 和有效负载上的 snapshot.payload 中。
    【解决方案3】:

    这是一个简单的更改,您的代码可以正常工作

    它对我有用

    1. 首先您需要使用数据类型任何[]的课程

    2. 您需要使用 subscribe 方法而不是直接将 valueChanges() 值存储到变量中

    3. 由于 Angular 旧版本直接支持 valueChanges() 方法来获取值,但在最新的 Angular 版本中,您需要使用 subscribe 方法 并像这样分配值。 p>

    courses : any[]; constructor(db:AngularFireDatabase){ db.list('/courses').valueChanges().subscribe(courses=&gt; { this.courses=courses; console.log(this.courses); });

    【讨论】:

    • 欢迎来到 Stack Overflow。请edit您的回答解释您对代码所做的更改如何解决问题,以便对其他有类似问题的用户有用。在 Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它是如何解决问题的。
    • 如果您想帮助他人,请对您的回答进行更多解释。
    猜你喜欢
    • 2018-11-06
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多