Angular 5用httpget填充空数组

时间:2018-03-16 14:19:11

标签: angular typescript rxjs observable angular5

我有一个空数组(productsWithCategory),我尝试在click事件上填充它。但它不是第一次点击工作。当我单击一次时,数组不会填充。首次点击后,一切正常。但我真的不知道为什么。你能救我吗?

抱歉我的英文。

category.component.html:



<h4 class="page-header">Categories</h4>
<div class="row">
  <div class="col-lg-3">
    <div class="list-group">
      <a 
        class="list-group-item" 
        *ngFor="let category of categoryList"
        (click)="getProducts(category.categoryId)">
        {{category.categoryName}}
      </a>
    </div>
  </div>
  <div class="col-lg-9">
    <div class="list-group">
      <a 
        class="list-group-item" 
        *ngFor="let product of productsWithCategory">
        {{product.productName}}
      </a>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

category.component.ts:

&#13;
&#13;
import { Component, OnInit, DoCheck } from '@angular/core';
import { CategoryService } from './category.service';
import { Category } from './category';
import { Product } from '../product/product';
import { ProductService } from '../product/product.service';

@Component({
  selector: 'app-category',
  templateUrl: './category.component.html',
  styleUrls: ['./category.component.css'],
  providers: [CategoryService, ProductService]
})
export class CategoryComponent implements OnInit {
  categoryList: Category[];
  productsWithCategory: Product[] = [];
  constructor(
    private categoryService: CategoryService, 
    private productService: ProductService
  ) {}

  ngOnInit() {
    this.getCategories();
  }

  getCategories() {
    return this.categoryService.getCategories().subscribe(p => this.categoryList = p);
  }

  getProducts(categoryId: number) {
    this.productsWithCategory = this.productService.getProductsByCategory(categoryId);
  }
}
&#13;
&#13;
&#13;

product.service.ts:

&#13;
&#13;
import { Injectable, Inject } from '@angular/core';
import { Product } from './product';
import { ProductList } from './product-list.mock';
import { Http, Response } from '@angular/http'
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/do'
import 'rxjs/add/operator/catch'

@Injectable()
export class ProductService {
  constructor(
    private http: Http, 
    @Inject('apiUrl') private apiUrl
  ) {}

  productsByCategory: Product[] = [];
  getProducts(): Observable < Product[] > {
    return this.http.get(this.apiUrl + "products").map(response => response.json());
  }

  getProductsByCategory(categoryId: number) {
    this.getProducts().subscribe(x => this.productsByCategory = x.filter((s: Product) => s.categoryId == categoryId, x));

    **
    * //this.productsByCategory => is empty on first click***
    return this.productsByCategory;
  }
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

this.getProducts()是一个异步操作。因此,如果您在调用该函数后返回this.productsByCategory,则调用将无法完成。在那之后,当然,如果你调用该函数,异步操作将(可能)完成,你将收到你检索到的最后一个数据。实际上,您可以检索错误的结果,因为您总是通过上次完成的调用过滤产品,而忽略您作为参数传递的实际categoryId

事实上,如果你进行多次调用并且他们停止工作(因为你失去了与服务器的连接),你会保持“接收”数据,尽管这些数据不会改变。

您应该从getProductsByCategory返回一个Observable:

return this.getProducts().filter(s => s.categoryId === categoryId);

然后你可以在调用函数中订阅observable,或者在模板中使用async管道。