问题描述
我有一个Angular 4应用.
I have an Angular 4 app.
我有一项通过API URL从Firebase数据库中获取数据的服务:
I have a service that fetch data from Firebase database by API URL:
import { Product } from './../models/product';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AppSettings } from '../app-settings';
@Injectable()
export class ProductsService {
products = [];
constructor(private http: HttpClient) { }
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(AppSettings.DB_API_ENDPOINT + '/products.json',);
}
}
以及显示该数据的组件:
And the component that displays that data:
import { Product } from './../../models/product';
import { Component, OnInit, Input } from '@angular/core';
import { ProductsService } from '../../services/products.service';
import { CategoriesService } from '../../services/categories.service';
@Component({
selector: 'products-list',
templateUrl: './products-list.component.html',
styleUrls: ['./products-list.component.scss']
})
export class ProductsListComponent implements OnInit {
products: Product[];
numberOfProducts: number;
page: number;
constructor(private productsService: ProductsService, private categoriesService: CategoriesService) {
this.page = 1;
this.numberOfProducts = 0;
this.products = [];
}
ngOnInit() {
this.productsService.getProducts().subscribe(products => {
console.log(products[0].getId());
this.products.push(products[0] as Product);
this.numberOfProducts = this.products.reduce((prev, el) => {
return prev + el.qtyAvailable;
}, 0);
});
}
qtyChange(qty: number) {
this.numberOfProducts -= qty;
}
}
和模型Product
:
export class Product {
$key: string;
qty: number;
isSoldOut: boolean;
constructor(
private id: number,
private name: string,
private description: string,
public qtyAvailable: number,
private price: number,
private image: string,
public category: string
) {
this.isSoldOut = false;
this.qty = 0;
}
isAvailable() {
return !this.isSoldOut;
}
getImageUrl() {
return '/assets/images/products/' + this.image;
}
public getId(): number {
return this.id;
}
getPrice() {
return this.price;
}
getDescription() {
return this.description;
}
getName(): string {
return this.name;
}
}
在该组件的视图中,我使用模型Product
中的product.isAvailable()
方法.我在控制台ERROR TypeError: _co.product.isAvailable is not a function
中收到错误消息.但是,当我在服务中键入products[0].id
时,在编译时会收到错误消息,该id
是Product
的私有数据.由于出现此错误消息,因此显示并分页了产品列表,但没有数据.
In the view of that component I use product.isAvailable()
method from the model Product
. I get th error message in console ERROR TypeError: _co.product.isAvailable is not a function
. But when I type products[0].id
in the service I get the error message while compile, that id
is a private of Product
. The list of producsts is displayed and paginated but without data, because of this error message.
推荐答案
这是在Rxjs中进行组织的更好方法.这将处理您的服务方法中的所有内容:
Here is a better way to organize this in Rxjs. This will handle everything inside your service mrthod:
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(AppSettings.DB_API_ENDPOINT + '/products.json',)
.switchMap(res => res); // make the retrieved list an Observable itself
.map(product => new Product(product.name // etc)) // map every json object to an instance of your class
.toArray(); // when the list is over, the Observable created from the json list will complete, and all of the emitted values will be stored in an array
}
作为参考,请参见以下链接: switchMap运算符, toArray运算符
For reference see these links: switchMap operator, toArray operator
这种方式更简洁,易读且更具反应性
This way is more cleaner, readable and in a more reactive style
这篇关于在RxJS中订阅后,对象类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!