使用快照更改检索Firebase对象

时间:2018-11-18 07:25:44

标签: angular 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>

我遇到的错误:

  

错误TypeError:无法读取未定义的属性“ title”   错误错误TypeError:changes.map不是函数

1 个答案:

答案 0 :(得分:0)

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

  1. 您在组件类中有一个名为Product的属性,但是随后您在模板中使用了product
  2. 此外,Product的类型很可能为Observable。因此,您必须在组件类中subscribe对其进行操作,或者必须使用async管道在模板中对其进行包装。
  3. 当您需要使用snapshotChanges时,您正在使用valueChangesvalueChanges将为您提供Observable,您可以直接订阅。我不太确定您为什么要使用map并在拥有key作为key的情况下使用para_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>