Angular:以可重用/清洁方法将 API 数据转换为新数据类型

0 rxjs typescript angular angular10

我正在尝试将 API 响应转换为完全不同的 ViewModel,用于多个组件。

a) 一种解决方案是直接在 API 代理中映射/管道数据,但是如果我只想要普通的原始 API 数据,那么 API 代理不是很可重用。

b) 这种模型-适配器模式可能不起作用,因为在示例中,适配器创建了与 API 相同的数据对象类型。https://florimond.dev/blog/articles/2018/09/sumption-apis-in-angular-the-model-adapter-pattern/。我们下面的数据转换器,带来了完全不同的一个。

寻找任何其他好的解决方案。

常规API:

export class ProductService {
  private readonly apiUrl = environment.baseUrl + '/api/CalculateProducts/';
  constructor(private httpClient: HttpClient) { }

  getProductData(
    productValuationDtoRequest: ProductValuationDtoRequest
  ): Observable<ProductValuationResponse>  {
    return this.httpClient.request<ProductValuationResponse>('post', this.apiUrl,
      {body: productValuationDtoRequest}
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

数据转换器:

export class CalculateProductModelService {
  constructor() { }

  convertData(
    productValuationResponse: ProductValuationResponse): CalculateCostModel  {

    const calculateProductModel: CalculateProductModel = {
      valuationAttribute: productValuationResponse?.productValuationDetail[0]?.productValuationAttribute?.description,
      livingAreaQuantity: productValuationResponse?.productValuationDetail[0]?.quantity,
      livingAreaRate: productValuationResponse?.productValuationDetail[0]?.improvementUnitValue * 1.03,
      livingAreaValue: productValuationResponse?.productValuationDetail[0]?.attributeTotalImprovementValue,
      numberOfUnits: productValuationResponse?.numberOfUnits * 2,
      replacementCostNew: productValuationResponse?.replacementCostNew,
      goodPercentage: productValuationResponse?.percentageGood,
      goodValue: productValuationResponse?.replacementCostNew * (100 - productValuationDto?.percentageGood) / 100,
      total: productValuationResponse?.totalImprovementValue
    };
    return calculateProductModel;
  }
Run Code Online (Sandbox Code Playgroud)

Pic*_*cci 7

如果我理解正确,我会添加一个方法来ProductService返回模型,这样ProductService最终会有 2 个方法,一个用于原始 API 数据,一个用于模型。

新方法将在内部使用当前getProductData方法来获取数据并CalculateProductModelService执行转换。

代码看起来像

export class ProductService {
  private readonly apiUrl = environment.baseUrl + '/api/CalculateProducts/';
  constructor(private httpClient: HttpClient, 
     private productModelService: CalculateProductModelService) { }

  getProductData(
    productValuationDtoRequest: ProductValuationDtoRequest
  ): Observable<ProductValuationResponse>  {
    return this.httpClient.request<ProductValuationResponse>('post', this.apiUrl,
      {body: productValuationDtoRequest}
    );
  }

  getProductModel(
    productValuationDtoRequest: ProductValuationDtoRequest
  ): Observable<CalculateProductModel>  {
    return this.getProductData(productValuationDtoRequest).pipe(
      map(rawData => productModelService.convertData(rawData))
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我使用依赖喷射来喷射CalculateProductModelServiceProductService。这种方式CalculateProductModelService不依赖于http调用并且可以很容易地进行测试。