簡體   English   中英

Angular 使用 RxJS - 當 JSON 對象具有多個屬性時如何映射數據

[英]Angular using RxJS - How to map data when JSON object has multiple properties

我的代碼最初有效,直到我需要更改 JSON 對象的結構。 這是我的原始 JSON 對象結構,它只是我的 API 返回的產品的簡單列表。 為簡潔起見,我縮寫為:

[{"PicFile":"11382","ShortDesc":"At Home Slot Machine","ActualPrice":12.99, .... }]

在我的產品服務中,我調用我的 API 並返回一個轉換為我的產品模型的列表:

getProductsByCategory(categoryCode: string): Observable<Product[]> {
let url = this.baseAPIUrl + .....
return this.httpClient.get(url)
       .pipe(
         map((data: any[]) => data.map((item) => this.adapter.convert(item)))
     );
}

這是我的適配器代碼。 我創建了一個可以接收任何類型對象的通用適配器,這是它的實現:

import { Injectable } from "@angular/core";
import { Adapter } from "./adapter";

export class Product {
    constructor(
        public PicFile: string,
        public ShortDesc: string,
        public ActualPrice: number,
        .... other properties here

    ) { }
}

@Injectable({
    providedIn: "root",
})
export class ProductAdapter implements Adapter<Product> {
    convert(item: any): Product {   
        return new Product(item.PicFile, item.ShortDesc, item.ActualPrice, .... );
    }
}

在我的產品組件中,我訂閱了從服務返回的 observable:

 loadAllProductsByCategory(categoryCode: string) {
        this.loadingSubject.next(true);

        this.productService.getProductsByCategory(categoryCode).pipe(
            catchError(() => of([])),
            finalize(() => this.loadingSubject.next(false))
        )
            .subscribe(products => this.productsSubject.next(products));
    }

這與我的簡單 JSON 結構完美搭配。 我需要為分頁目的添加一個計數屬性,並且將來很可能會添加其他屬性。 新的 JSON 對象具有保存產品列表的“Data”屬性和名為“Count”的屬性。

{"Data":[{"PicFile":"11382","ShortDesc":"At Home Slot Machine","ActualPrice":12.99, ...}], "Count":41}

所以,我的問題是如何更改我的服務代碼以查找“數據”屬性並進行轉換?:

return this.httpClient.get(url)
       .pipe(
         map((data: any[]) => data.map((item) => this.adapter.convert(item))) <-- how to look for "Data" property and convert only that list, not the whole object?
     );

我嘗試了幾件事,包括在此處訂閱,但隨后將其轉換為訂閱,我需要返回可觀察對象。 我相信它可以完成,但我對 Angular 和 RxJS 還很陌生。 我似乎無法正確找出映射語法。

提前感謝您提供的任何幫助,吉姆

如果返回的數據結構發生變化,則需要更新服務中的map

 return this.httpClient.get(url).pipe(
    map( (data: any) => data.Data.map((item) => this.adapter.convert(item)) )
);

您可能應該更改傳遞到地圖中的屬性名稱以避免混淆。 IE

(resp: any) => resp.Data.map((item) => this.adapter.convert(item))

從服務返回的數據結構已經從 Array 變為 Object。 因此,您必須更改映射過程

此更新后的代碼只會從您的響應中返回Data數組。

如果還需要返回計數,則需要更新服務方法getProductsByCategory以返回包含計數和數據的對象。

您可以嘗試以下方法:

return this.httpClient.get(url).pipe(
  map((response: any) => {
    response.data=response.data.map((item) => this.adapter.convert(item));
    return response;
  })
);

從服務獲取 JSON 時的常見映射模式是使用響應中的數據創建或豐富對象

 return this.httpClient.get(url).pipe(
    map(response => ({
      ProcessingTimeStamp: Date.now(),
      fullName: `${response.productName} (${response.productShortHand})`,
      count: response.count,
      data: response.Data.map(item => this.adapter.convert(item)),
      foo: response.bar,
      message: `I can sell you ${count}, of ${response.productShortHand} for cheap! Buy from me!`
    }))
);

此模式將響應轉換為一個對象,您可以稍后隨意使用。 這里一個響應變成了一個對象,形式如下:

{
  ProcessingTimeStamp: number,
  fullName: string,
  count: number,
  data: item[],
  foo: any,
  message: string
}

你真的不受你能做什么的限制。 如果它適用於 TS/JS,你可以做到。 您可以推送函數或嵌套的 observables 等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM