无法从我的服务中获取数据到我的组件中

Cant get the data from my service into my component

我在 Angular 8 最近尝试创建一个简单的 Web 应用程序来提高我的技能时遇到了问题。 我正在尝试制作一个 table 网络应用程序,table 的 html 看起来像这样,并使用从组件 class 中的服务填充的产品数组。

 <table class = "table" *ngIf = "Products && Products.length!=0">
                <thead>
                    <tr>
                        <th>
                            <!-- ternary statement to change the image text -->
                            <button class = "btn btn-primary" (click)= 'toggleImage()'>{{ showImage ? 'Hide Image' : 'Show Image'}}</button>

                        </th>
                        <th>Product</th>
                        <th>Code</th>
                        <th>Available</th>
                        <th>Description</th>
                        <th>Price</th>
                        <th>Rating</th>
                    </tr>
                </thead>
                <tbody>
                    <tr *ngFor = "let product of filteredProducts">
                        <td>
                            <!-- //the image will only show if show image is true -->
                            <img *ngIf = 'showImage' 
                             [src]='product.imageUrl'
                             [title]='product.productName | uppercase'
                             [style.width.px]= 'imageWidth'
                             [style.margin.px]="imageMargin">
                        </td>
                        <td>{{product.productName}}</td>
                        <td>{{product.productCode | lowercase | convertToSpaces: '-'}}</td>
                        <td>{{product.releaseDate}}</td>
                        <td>{{product.description}}</td>
                        <td>{{product.price | currency: 'EUR'}}</td>
                        <td><pm-star [rating]= "product.starRating" (ratingClicked)= "onRatingClicked($event)"></pm-star></td>

                    </tr>

                </tbody>

            </table>

我写了一个服务 class 看起来像这样

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, tap, map } from 'rxjs/operators'
import { IProduct } from '../../app/components/product-list/product';

@Injectable({
  providedIn: 'root'
})

export class ServiceService{
  private productUrl = "http://localhost:4200/assets/data.json"
  constructor(private http: HttpClient) { }

  getProducts(): Observable<IProduct[]> {
    return this.http.get<IProduct[]>(this.productUrl)
      .pipe(
        tap(data => console.log('All: ' + JSON.stringify(data))),
        catchError(this.handleError));
  }
}

该服务包含一个 getProducts 函数,该函数 returns 从 json 数据中观察到的只是一个本地文件,并将数据打印到控制台。

JSON 文件包含多个对象,例如

 {
    "productId": 5,
    "productName": "Hammer",
    "productCode": "TBX-0048",
    "releaseDate": "May 21, 2019",
    "description": "Curved claw steel hammer",
    "price": 8.9,
    "starRating": 4.8,
    "imageUrl": "assets/images/hammer.png"
  },

在我的 component.ts clss 中,我在 ngOnInit 函数中有一些我认为能够订阅服务并将数据添加到相关数据结构的逻辑。这里是component.tsclass

import { Component, OnInit } from '@angular/core';
import { IProduct } from './product';
import { ServiceService } from '../../service/service.service';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})

export class ProductListComponent implements OnInit {
  pageTitle = 'Product List';
  imageWidth = 50;
  imageMargin = 2;
  showImage = false;
  errorMessage: string;

  _listFilter = '';
  get listFilter(): string {
    return this._listFilter;
  }
  set listFilter(value: string) {
    this._listFilter = value;
    this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
  }

  filteredProducts: IProduct[] = [];
  products: IProduct[] = [];

  constructor(private productService: ServiceService) {

  }

  onRatingClicked(message: string): void {
    this.pageTitle = 'Product List: ' + message;
  }

  performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
      product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
  }

  toggleImage(): void {
    this.showImage = !this.showImage;
  }

  ngOnInit(): void {
    this.productService.getProducts().subscribe({
      next: products => {
        this.products=products,
        this.filteredProducts = this.products;
      },
      error: err => this.errorMessage =err
    });
  }
}

正如您在 ngOnInit 中看到的那样,我订阅了 observable,并且还使用来自 observable 的产品数据填充了产品数组,但是我的产品数组仍然是空的,当绑定到.htmlclass。 感谢您在高级方面的帮助。

问题出在模板中,你有一个*ngIf:

<table class="table" *ngIf="Products && Products.length!=0">

您的组件没有变量Products,它是products小写P。此外,您实际上不需要检查 length,因为如果数组没有项目,angular 甚至不会尝试呈现 *ngFor。但是可以肯定的是,始终保持安全;)但是只需检查 products.length 就足够了,不需要 !=0.

对 *ngIf 进行以下更改:

<table class="table" *ngIf="products && products.length">