首页 > 解决方案 > 使用快照更改检索 Firebase 对象

问题描述

我想使用 . 从我的产品列表中检索一种产品snanshotChanges。这是我的代码一步一步:

这是界面:

export interface Product {
  title: string;
  price: number;
  category: string;
  imageUrl: string;
}

这是服务:

我使用 db.object 从 firebase 读取对象。

import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireObject, AngularFireList } from '@angular/fire/database';
import { Product } from './models/product';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  constructor(private db: AngularFireDatabase) { }

  create(product: Product) {
   return this.db.list('/products').push(product);
  }

  getAll(): AngularFireList<Product> {
    return this.db.list('/products');
  }

  get(productId): AngularFireObject<Product> {
    return this.db.object('/products/' + productId);
  }

  }

这是 ProductDetailsComponent 类:

import { Component, OnInit } from '@angular/core';
import { CategoryService } from 'app/category.service';
import { ProductService } from 'app/product.service';
import { Router, ActivatedRoute } from '@angular/router';
import {map} from 'rxjs/operators';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent implements OnInit {

  categories$;
  categories;
  product = {};

  constructor(private router: Router, private route: ActivatedRoute,
    categoryService: CategoryService,
    private productService: ProductService) {
    this.categories = categoryService.getCategories();
    this.categories$ = this.categories.snapshotChanges().map(changes => {
    return changes.map(c => ({ key: c.payload.key, ...c.payload.val()}));
     });


  
    const param_id = this.route.snapshot.paramMap.get('id');
    if (param_id) {
       this.productService.get(param_id).snapshotChanges().pipe(map(changes => {
        return changes.payload.val() })).subscribe(p => this.product = p);

    }
  }


  save(product) {
   this.productService.create(product);
   this.router.navigate(['admin/products']);
   }

   ngOnInit() {






      }
    }

这是模板:

<input 
  #title="ngModel" 
  [(ngModel)] = "product.title" 
  name="title" 
  id="title" 
  type="text" 
  class="form-control" 
  required>

我得到的错误:

错误类型错误:无法读取未定义错误的属性“标题”错误类型错误:changes.map 不是函数

标签: angularfirebase

解决方案


您当前的实施存在很多问题。

  1. 您有一个Product在组件类中命名的属性,但随后您product在模板中使用。
  2. 此外,Product很可能是 type Observable。因此,您必须subscribe在组件类中对其进行处理,或者您必须使用async管道将其解包到模板中。
  3. snapshotChanges当你需要使用的是valueChanges. valueChanges会给你一个Observable你可以直接订阅的。我不太确定您为什么要使用map然后在您key已经拥有.keypara_ID

试试这个:

<div *ngIf="Product | async as product">
  <input 
    #title="ngModel" 
    [(ngModel)] = "product.title" 
    name="title" 
    id="title" 
    type="text" 
    class="form-control" 
    required>
</div>

在这里,我们检查是否Product已初始化,然后我们使用管道并为未包装的值async创建一个别名。product

更新:

如果您不想使用async管道,则可以直接订阅Observable。就是这样:

const para_ID = this.route.snapshot.paramMap.get('id');
if (para_ID) {
  this._product = this.productService.get(para_ID);

  this._product.valueChanges()
    .subscribe(res => this.Product = res);
}

然后在您的模板中:

<div *ngIf="Product">
  <input 
    #title="ngModel" 
    [(ngModel)] = "Product.title" 
    name="title" 
    id="title" 
    type="text" 
    class="form-control" 
    required>
  ...
</div>

推荐阅读