我想使用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不是函数
答案 0 :(得分:0)
您当前的实现存在很多问题。
Product
的属性,但是随后您在模板中使用了product
。Product
的类型很可能为Observable
。因此,您必须在组件类中subscribe
对其进行操作,或者必须使用async
管道在模板中对其进行包装。snapshotChanges
时,您正在使用valueChanges
。 valueChanges
将为您提供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>