angularjs 如何将Angular GET请求响应数据加载到不同的列表中?

cld4siwp  于 2023-05-05  发布在  Angular
关注(0)|答案(2)|浏览(123)

我是Angular的新手,我想构建一个使用我的REST API(用Django构建)的前端应用程序。我已经找了两天了,但是我没有得到一个满意的答案。我试图问聊天GPT,但它似乎总是忙碌(无法访问后,我登录)。我已经创建了一个服务和模型,使一切都很舒适,但它不起作用。
我尝试将API数据加载到HomeComponent中的几个列表中。

以下是我的模型:

export interface ProductList{
  total_pages: number;
  current_page: number;
  has_next: boolean;
  has_prev: boolean;
  page_items_count: number;
  items_per_page: number;
  data: [
    id: number,
    name: string,
    picture: string,
    price: number,
    discount: number | null,
    saved_amount: number,
    discount_percent: number | null,
    slug: string,
    is_available: boolean,
    ratings_average: number,
    ratings_count: number,
    date: string,
    uuid: string,
    extra_data: any,
    category: Category,
  ]
}

export interface ProductDetail{} // For now, I haven't designed ProductDetail model. Just declared it.

我的服务

import { Injectable } from '@angular/core';
import { Observable, catchError, of, map } from 'rxjs';
import { ProductList, ProductDetail } from '../../models/products.models';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class ProductsService {
  baseUrl = "http://127.0.0.1:8000/api";
  headers = new HttpHeaders({
    'Content-Type': 'application/json',
  });

  constructor(private http: HttpClient) { }

  private handleError(error: Error, errorValue: any) {
    return of(errorValue);
  }


  getProductList(): Observable<ProductList[]> {
    const productUrl = `${this.baseUrl}/products/`
    return this.http.get<ProductList[]>(productUrl, { headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, []))
    );
  }

  getProductDetail(product_id: number): Observable<ProductDetail|undefined> {
    const productDetaiLlUrl = `${this.baseUrl}/products/${product_id}/`
    return this.http.get<ProductDetail>(productDetaiLlUrl, { headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, undefined))
    );
  }

  getUnavailableProductList(): Observable<ProductList[]> {
    const productUrl = `${this.baseUrl}/products/unvailable/`
    return this.http.get<ProductList[]>(productUrl, { headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, []))
    );
  }

  searchProducts(query: string|null): Observable<ProductList[]> {
    const params = query ? new HttpParams().set('q', query): {}
    const searchUrl = `${this.baseUrl}/products/search/`
    return this.http.get<ProductList[]>(searchUrl, { params: params, headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, []))
    );
  }

}

我的HomeComponent

import { Component, OnInit } from '@angular/core';
import { ProductList } from '../../models/products.models';
import { ProductsService } from 'src/app/services/products/products.service';

@Component({
  selector: 'app-homepage',
  templateUrl: './homepage.component.html',
  styleUrls: ['./homepage.component.css']
})
export class HomepageComponent implements OnInit {
  public productList: ProductList[];
  products = [];
  public total_pages: number;
  public current_page: number;
  public has_next: boolean;
  public has_prev: boolean;
  public page_items_count: number;
  public items_per_page: number;
  public _products = []

  constructor (private productService: ProductsService) {}

  ngOnInit() {
    this.productService.getProductList().subscribe((res) => {
      this.productList = res; 
      // Here, I want to load values of the key "data" (a list of products) into this.productList
      // And also the value of key "total_pages" in this.total_pages and so on (for the rest of the other variables that I declared.
    });
  }
}

当我发送GET请求时,我收到了正确的数据,但我不能循环这些数据。如果执行*ngFor="let product of productList.data",则显示错误。出于某种原因,我想单独访问所有这些数据。
使用console.log(this.productList),整个响应被加载,但我只想从键“www.example.com”访问产品productList.data并显示它们。但问题是,我不能单独加载数据,也不能循环通过“productList.data”来获取产品。
下面是当我向产品发送GET请求时的响应模式(键“data”是产品列表)Response schema

那么我如何获取这些数据,将它们加载到不同的列表中并将它们发送到我的HTML视图?

bvhaajcl

bvhaajcl1#

ProductList接口中data的数据类型是错误的,如果data应该是一个数组,则在Typescript中定义它:

export interface ProductList { 
  ...
  ...
  data: MyData[]; // MyData is the data type for data property
} 

export interface MyData {
  id: number,
  name: string,
  picture: string,
  price: number,
  discount: number | null,
  saved_amount: number,
  discount_percent: number | null,
  slug: string,
  is_available: boolean,
  ratings_average: number,
  ratings_count: number,
  date: string,
  uuid: string,
  extra_data: any,
  category: Category
}

此外,productList类属性是一个数组,给出了public productList: ProductList[];的定义,因此为了访问单个data,需要使用ngFor迭代两次:

<div *ngFor="let product of productList">
  <div *ngFor="let myData of product.data">
    <p>{{ myData.discount }}</p>
    <p>{{ myData.name }}</p>
    <p>{{ myData.uuid }}</p>
    ...
  </div>
</div>
rhfm7lfc

rhfm7lfc2#

已解决

当我向后端发送请求时,它不会返回产品列表,而是返回一个包含产品列表的对象(带有data键:"data": []所以我没有告诉ProductService返回一个产品列表,而是变成了一个对象。这个对象包含一个产品列表,就像我说的。
以下是我的新模型:products.models.ts

export interface Product{
  id: number;
  name: string;
  picture: string;
  price: number;
  discount: number | null;
  saved_amount: number;
  discount_percent: number | null;
  slug: string;
  is_available: boolean;
  date: string;
  ratings_average: number;
  ratings_count: number;
  uuid: string;
  extra_data: any;
  category: Category;
}

export interface ProductObject{
  total_pages: number;
  current_page: number;
  has_next: boolean;
  has_prev: boolean;
  page_items_count: number;
  items_per_page: number;
  data: Product[]; // products are available here in "data" key
}

我的新产品.服务.ts

import { Injectable } from '@angular/core';
import { Observable, catchError, of } from 'rxjs';
import { ProductObject, ProductDetailObject } from '../../models/products.models';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';



@Injectable({
  providedIn: 'root'
})
export class ProductsService {
  baseUrl = "http://localhost:8000/api";
  headers = new HttpHeaders({
    'Content-Type': 'application/json',
  });

  constructor(private http: HttpClient) { }

  private handleError(error: Error, errorValue: any) {
    return of(errorValue);
  }


  getProductList(): Observable<ProductObject> {
    const productUrl = `${this.baseUrl}/products/`
    return this.http.get<ProductObject>(productUrl, { headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, []))
    );
  }

  getProductDetail(product_id: number): Observable<ProductDetailObject|undefined> {
    const productDetaiLlUrl = `${this.baseUrl}/products/${product_id}/`
    return this.http.get<ProductDetailObject>(productDetaiLlUrl, { headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, undefined))
    );
  }

  getUnavailableProductList(): Observable<ProductObject> {
    const productUrl = `${this.baseUrl}/products/unvailable/`
    return this.http.get<ProductObject>(productUrl, { headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, []))
    );
  }

  searchProducts(query: string|null): Observable<ProductObject> {
    const params = query ? new HttpParams().set('q', query): {}
    const searchUrl = `${this.baseUrl}/products/search/`
    return this.http.get<ProductObject>(searchUrl, { params: params, headers: this.headers }).pipe(
      catchError((error) => this.handleError(error, []))
    );
  }

}

正如你所看到的,我现在返回了一个API响应的对象。
所以我找到了正确/完美的方法来回答我的问题(如何将Angular GET请求响应数据加载到不同的列表中?

  • 我现在可以重组从服务中获得的数据,并将数据加载到不同的变量中。*

下面是我的homepage.component.ts现在的样子:

import { Component, OnInit } from '@angular/core';
import { ProductObject, Product } from '../../models/products.models';
import { ProductsService } from 'src/app/services/products/products.service';

@Component({
  selector: 'app-homepage',
  templateUrl: './homepage.component.html',
  styleUrls: ['./homepage.component.css']
})
export class HomepageComponent implements OnInit {

  constructor (private productService: ProductsService) {}

  // PRODUCTS vars
  productObject: ProductObject;
  products: Product[];
  productsTotalPages: number;
  productsCurrentPage: number;
  productsHasNext: boolean;
  productsHasPrev: boolean;
  productsPageItemsCount: number;
  productsItemsPerPage: number;

  ngOnInit() {
    // GET products data
    this.productService.getProductList().subscribe((productsData) => {
      this.productObject = productsData;

      this.products = productsData.data;
      this.productsTotalPages = productsData.total_pages;
      this.productsCurrentPage = productsData.current_page;
      this.productsHasNext = productsData.has_next;
      this.productsHasPrev = productsData.has_prev;
      this.productsPageItemsCount = productsData.page_items_count;
      this.productsItemsPerPage = productsData.items_per_page;
    });
  }
}

我现在可以在HTML模板中迭代products

相关问题