【问题标题】:How to assign a Firebase snapshot object to an Angular type如何将 Firebase 快照对象分配给 Angular 类型
【发布时间】:2021-05-29 23:17:45
【问题描述】:

我在 Angular 中创建了一个客户服务,以从 Firebase 实时数据库中获取客户列表,如下所示:

  getCustomers() {
       return this.db.list('/customers', ref => ref.orderByChild('name')).snapshotChanges(); }

这会成功返回一个 JSON 数组。

然后我定义了Customer接口如下:

export interface Customer {
  name: string;
  address: string;
  type: string;
  phone: string;}

现在,在组件中,我正在尝试访问客户信息,如下所示:

customers: Customer[];
subscription: Subscription;
constructor(private customerService: CustomerService) {
this.subscription = this.customerService.getCustomers().subscribe(customers => this.customers = customers.map(c => c.payload.val()));

}

这给了我一个编译错误“Type Unknow is not assignable to type Customer[]”。 我的问题是:

  1. 将 payload().val() JSON 输出转换为客户类型的最佳方法是什么?
  2. 如何访问每条记录的密钥?(这是我的页面所必需的)。

非常感谢。

------ 根据 Le_Buzz 的建议和指导,更新了工作解决方案 ------

//首先我更新了客户界面以包含字段“key”,如下所示:

export interface Customer {
  key: string;
  name: string;
  address: string;
  type: string;
  phone: string;}

//声明customers数组如下:

customers: Customer[] = [];

//然后订阅Observable如下:

subscription: Subscription;
  this.subscription = this.customerService.getCustomers().subscribe(cus => {
  cus.forEach(cus => {
    const values = cus.payload.val();
    const key = cus.payload.key;
    this.customers.push({ name: values["name"], key: key, address: values["address"], type: values["type"], phone: values["phone"] })
  })
}) 

【问题讨论】:

    标签: json angular firebase-realtime-database angularfire


    【解决方案1】:

    首先,我建议你将客户信息从firebase变成一个数组,然后使用数组来构建客户对象(可能有更简洁的方法,但这是我现在能想到的)。至于第二个问题,您可以从 subscribe 方法中获取密钥。请参阅下面对我有用的代码。

    注意:我创建了以下变量:

    1. productArray 从我的订阅方法构建结果。
    2. listData - 我的表的数据源(我在表中呈现了 firebase 调用)。
    3. displayColumnscolumnsTo Display - 这些是特定于我的桌子的。您的实现会有所不同,因此您可以随意忽略/修改与这些变量对话的代码。

    基本上,多注意下面的前 8 行:

    this.productService.getProducts().subscribe(
      list => {
        this.productsArray = list.map(item => {
          return {
            $key: item.key,
            ...item.payload.val()
          };
        })
        this.listData = new MatTableDataSource(this.productsArray);
        this.displayedColumns = Object.values(Object.keys((this.productsArray)[0]))
        this.columnsToDisplay = this.displayedColumns.slice();
        this.columnsToDisplay.push("actions");
      }
    );
    

    最后,根据使用的角度版本,您可能希望通过将 customers: Customer[]; 更改为 customers: Customer[] = []; 来初始化客户变量

    如果它解决了您的问题,请将此标记为已回答。谢谢!

    【讨论】:

    • 您好,非常感谢您的快速回复。这可行,但在我的 Angular 版本中,它给出了一个警告“@deprecated - 使用观察者而不是完整的回调”。我使用 map 运算符找到了以下帖子:|stackoverflow.com/questions/57939474/… 但它返回一个 Observable,我不知道如何从中读取值。
    • 究竟什么是弃用的?我在我的案例中使用了地图,所以我不确定问题是什么。如果要使用 observable,可以从 rxjs 导入 o​​bservable,将变量声明为 observable,然后执行如下操作:this.items = db.list('items').valueChanges()。您还可以在代码的不同阶段console.log 帮助调试。
    • 根据我的代码, getProducts().subscribe 已被贬低。编辑删除了 subscribe 关键字并给出了我上面提到的警告。
    • 这很奇怪。我正在使用 Angular11,它不会抛出该错误。你用的是什么版本?尝试将subscription 声明为可观察对象,即subscription: Observable<any[]>
    • 非常感谢 Le_Buzz,在您的建议和指导下,我能够为我想出一个可行的解决方案。我已经更新了上面的原始帖子。我正在使用 Angular 11、Angular/fire 6.1.4 和 rxjs 6.6.6
    猜你喜欢
    • 2021-01-02
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 2020-05-22
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多