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>
我得到的错误:
错误类型错误:无法读取未定义错误的属性“标题”错误类型错误:changes.map 不是函数
解决方案
您当前的实施存在很多问题。
- 您有一个
Product
在组件类中命名的属性,但随后您product
在模板中使用。 - 此外,
Product
很可能是 typeObservable
。因此,您必须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>
推荐阅读
- node.js - 节点 axios 返回空状态和 curl 返回 200 为 tiktok
- validation - 我正在尝试使用 Google 表格中的数据验证来仅接受十六进制颜色 - 任何帮助表示赞赏
- javascript - 刷新页面的一部分,部分在 rails
- python - 从列表中获取数字并绘制模式
- signalr - 循环中的 SignalR
- python - 这个“自我未定义”错误是范围问题吗?
- javascript - 如何声明函数以便在 Typescript 中分配对象时可用?
- c# - c#(Linq)中的自由文本搜索多列
- typescript - 将方法签名限制为仅允许事件映射中定义的类型的有效负载
- python - A.split(B) 其中 a 和 b 是音频文件