将JSON对象映射为可观察到以用于ngFor Angular

时间:2019-02-26 18:29:13

标签: angular components angular-services ngfor

我试图将JSON对象映射到我在我的角度应用程序中配置的可观察接口,我希望一旦将其映射,就可以将其用作输入来遍历ngFor。

不幸的是,我不相信我在正确配置我的服务,或者可能无法进行服务调用。

我将json对象作为单个对象返回,但是ngFor不能正确遍历返回的结果,对指出我可能忽略的内容的任何帮助将不胜感激。

//我正在尝试访问的界面

export interface IProduct {
   name: string;
   description: string;
   price: number;
   category: string;
   image: string;
}

//我正在尝试致电服务

private productList = new BehaviorSubject<IProduct[]|null>(null);
productListChanges$ = this.productList.asObservable();
constructor(private http: HttpClient) { }

getProds(): Observable<IProduct[]> {
     this.productList.next(null);
     return this.http.get<IProduct[]> 
                      ('http://localhost:4200/assets/data/products.json')
     .pipe(
        tap(data => this.productList.next(data)),
     );
 }

//致电服务

productsList: IProduct[] = [];

this.productService.getProds().subscribe((response: any) => {
  this.productsList = response.products[0] as IProduct[];
  console.log(this.productsList);
});

//尝试对获得的对象使用ngFor

<app-product *ngFor="let product of productsList" [prod]="product" ></app-product>

//服务调用中的控制台日志输出以下内容

logOutput from service call

3 个答案:

答案 0 :(得分:0)

在与Observables循环时尝试使用异步。

<app-product *ngFor="let product of productsList | async" [prod]="product" ></app-product>

答案 1 :(得分:0)

我看到您正在使用HTTP来提供JSON数据,这些数据很容易获取,就像来自资产文件夹中存在的静态文件的数据一样。我会避免通过HTTP调用来提供这些服务。我已经将您的代码重构为既可以提供静态数据,也可以使用相同的服务方法来支持远程数据查询。它还应该在单元测试期间提供帮助,因为异步测试是一场噩梦。

// Changed the Interface to a class
export class Product {
   name: string;
   description: string;
   price: number;
   category: string;
   image: string;
}

// Create a sample-data.ts file
export const ProductListData: Array<Product> = [
    {
       name: 'ProductName',
       description: 'Description',
       price: '9.99', // Maybe should be a number type and not string
       category: 'Test Category',
       image: 'your url for testing'
    }
]

// In service... 
import { of } from 'rxjs';
import { ProductListData } from './sample-data';
useSampleData = false;

getProducts(): Observable<Array<Product>> {
    if (useSampleData) {
        // Use this is your want to serve static JSON
        return of(ProductListData); // of() turns your readily avialable object into an obeservable promise
    } else {
    // Get from actual HTTP as async
        return this.http.get<Array<Product>>('http://localhost:4200/api/your-endpoint-url');
    }
 }
 
 
// In you Component...
public productList: Array<Product> = [];

this.productService.getProducts().subscribe(
    productList => {
      this.productsList = productList;
    },
    err => {
        console.log('Error: ', err);
    }
);

您的模板不需要更改。

答案 2 :(得分:0)

如控制台输出所示,productsList是一个对象,但是ngFor需要一个数组。

如果可以更改数据,应该可以轻松地将其更改为数组([...])而不是对象({...})。

否则,您有几个选项可以将代码中的结构转换为数组。例如,当使用Object.values()时,可以将当前结构转换为Array。另外,您也可以使用自Angular 6.1起可用的KeyValuePipe。也在这里https://stackoverflow.com/a/51491848/9999800

回答