Angular 角度2:由于接收服务器数据缓慢而导致接收错误
在服务类的构造函数中,我向服务器发出http调用,以检索存储在productCategories数组中的产品类别数据。然后在我的组件的ngInit()函数中,我调用了服务来检索productCategories数组,但是我得到一个错误,productCategories未定义 似乎正在发生的是,服务的构造器向服务器发出调用,然后在检索产品类别数据之前返回。当组件为此数据调用服务的getCategory(x,y)方法时,服务构造函数对服务器的上一次调用仍然没有完成,因此它声明productCategories数组未定义。然后调用完成,productCategories数组被记录到控制台 我该如何解决这个问题Angular 角度2:由于接收服务器数据缓慢而导致接收错误,angular,typescript,Angular,Typescript,在服务类的构造函数中,我向服务器发出http调用,以检索存储在productCategories数组中的产品类别数据。然后在我的组件的ngInit()函数中,我调用了服务来检索productCategories数组,但是我得到一个错误,productCategories未定义 似乎正在发生的是,服务的构造器向服务器发出调用,然后在检索产品类别数据之前返回。当组件为此数据调用服务的getCategory(x,y)方法时,服务构造函数对服务器的上一次调用仍然没有完成,因此它声明productCate
@Injectable()
export class ProductCategoryService {
private productCategories: ProductCategory[];
private categoriesUrl = "/api/product/categories";
constructor(private http: Http) {
console.log('ProductCategory.constructor() called');
this.getProductCategoriesDb();
}
private getProductCategoriesDb() {
console.log('ProductCategory.getCategories() called');
this.http.get(this.categoriesUrl)
.toPromise()
.then((response: Response) => {
this.productCategories = response.json();
console.log('this.productCategories = ' +
JSON.stringify(this.productCategories));
})
.catch(this.handleError);
}
public getProductCategory(name, type) {
return this.productCategories
.filter(category => (category.name == name && category.type == type))[0];
}
}
组成部分:
export class ProductCategoryComponent implements OnInit {
category: string;
type: string;
productCategory: ProductCategory = new ProductCategory();
constructor(private route: ActivatedRoute, private productCategoryService:
ProductCategoryService) { }
ngOnInit() {
this.route.params.subscribe(params => {
this.category = params["category"];
this.type = params["type"];
console.log("category = " + this.category)
console.log("type = " + this.type)
this.productCategory =
this.productCategoryService.getProductCategory(this.category, this.type);
console.log("productCategory = " + this.productCategory);
})
}
}
记录语句的顺序:
ProductCategory.constructor()调用----product category.service.ts:27
调用--product category.component.ts:23
错误:productCategories数组未定义:
ProductCategoryComponent_Host.html:1错误类型错误:无法读取未定义的属性“filter”
在ProductCategoryService.webpackJsonp…/../../../../../src/app/product category/product-category.service.ts.ProductCategoryService.getProductCategory(product category.service.ts:39)
在SafeSubscriber.\u下一步(产品类别.组件ts:27)
在SafeSubscriber.webpackJsonp…/../../../../rxjs/Subscriber.js.SafeSubscriber.\uu tryOrSetError(
最后打印productCategories数组---product category.service.ts:33
this.productCategories=[{u id:“599c5d93f36d286317108ffd”,“名称:”“家具”,“类型:”“客厅”,“图像:[{”标签:”“客厅”,“名称:”“客厅1.jpg”},{“标签:”“沙发”,“名称:”“客厅2.jpg”},{“标签:”“睡眠者”,“名称:”“客厅3.jpg”},{“标签:”“爱情座椅”,“名称:”“客厅4.jpg”},{“标签:”“椅子”,“名称:”“客厅5.jpg”},{“Ottomans”、“name”:“LivingRoom6.jpg”}、{“label”:“Chaisers”、“name”:“LivingRoom7.jpg”}、{“label”:“躺椅”、“name”:“LivingRoom8.jpg”}、{“label”:“Sectionals”、“name”:“LivingRoom9.jpg”}、{“label”:“不定期桌子”、“name”:“LivingRoom10.jpg”}、“物品”[“沙发”、“枕木”、“爱情座椅”、“椅子”、“Ottomans”、“不定期桌子”、“躺椅”、“不定期桌子”]}]简单的答案是:不要修改它,重写它。 您抛出的错误背后的推理是正确的,但也许在处理服务器的数据时,您应该考虑一种不同的方法。 这是第一步,可以进一步迭代改进
@Injectable()
export class ProductCategoryService {
productCategoriesSbj: ReplaySubject<ProductCategory[]> = new ReplaySubject();
private categoriesUrl = "/api/product/categories";
constructor(private http: Http) {
}
getProductCategoriesDb(): Observable<ProductCategory[]> {
return this.http.get(this.categoriesUrl)
.subscribe(response => this.productCategoriesSbj.next(response.json()))
.catch(this.handleError);
}
getProductCategory(categories: ProductCategory[], name: string, type: string) {
return categories.filter(category =>
(category.name == name && category.type == type)
)[0];
}
}
没有太多的解释,但我希望它能有所帮助。这肯定是一种改进。但唯一的问题是,每次调用GetProductDB()时,我都必须调用服务器.我使用构造函数是因为我希望可以在一次调用中检索类别数据并将其存储在数组中。有没有办法解决此问题?仍然从构造函数调用方法似乎不正确。在这种情况下,可能应该从功能模块主组件或
AppComponent
调用,如果它是唯一的模块。Reagring,将状态存储在服务中是可行的,而且行为主体
是一个很好的选择。我将更新答案。对不起,我的意思是编写回放主体
。
export class ProductCategoryComponent implements OnInit, OnDestroy {
category: string;
type: string;
productCategory: ProductCategory = new ProductCategory();
productCategorySub: Subscription = new Subscription();
constructor(private route: ActivatedRoute,
private productCategoryService: ProductCategoryService){
}
ngOnInit() {
this.route.params.subscribe(params => {
this.category = params["category"] || '';
this.type = params["type"] || '';
this.productCategoryService.getProductCategoriesDb();
productCategorySub = this.productCategoryService
.productCategoriesSbj
.subscribe(categories => {
// now categories contain parsed response from the server
this.productCategory = this.productCategoryService
.getProductCategory(categories, this.category, this.type);
});
})
}
}
ngOnDestroy() {
// unsubscribe from observable to avoid memory leaks
this.productCategorySub.unsubscribe();
}