Angular的HttpClient.get()泛型中可以使用非简单属性类型吗?(例如除了字符串或数字之外的其他类型)

26 浏览
0 Comments

Angular的HttpClient.get()泛型中可以使用非简单属性类型吗?(例如除了字符串或数字之外的其他类型)

我花了一整天的时间研究这个主题,但是没有找到任何线索。所有我找到的都是省略,也就是说,我读到的内容中没有提到在调用 Angular 4.4 的 HttpClient.get() 时可以使用非简单类型(我指的是)作为泛型接口(\"shape\")。\n以下是我想要实现的示例代码,以便更好地描述问题:\n// 这些是我真实代码中注入的库...这只是示例。\nimport { HttpClientModule } from \'@angular/common/http\';\nimport { Observable } from \"rxjs\";\nimport \'rxjs/Rx\';\ninterface IMyDataItem {\n // 在这个示例中,使用 @Types/Decimal.js\n // 似乎除了简单类型(number/string等),其他类型都存在这个“问题”\n results: decimal.Decimal[];\n}\nclass Service {\n doSomethingCool() {\n this._http\n .get(\"url://somewhere\")\n .subscribe(\n data => {\n // 调用 Decimal 类型属性的方法\n data.results[0].pow(3, 3);\n }\n );\n }\n}\n语法上它是可以编译的。TypeScript 正确解析了泛型的魔力,并且识别出 data.results 是一个类型为 Decimal 的数组。\n然而在运行时(在 Chrome 中,将代码转译为 Javascript 后),调用 pow() 方法失败,提示该方法不存在(实际上,调试显示它是一个普通的 Javascript 对象)。\n我对 TypeScript 和 Angular 4 都非常陌生,但对我来说,这种情况是合乎逻辑的。我只是要求泛型的 get() 方法将请求处理为一个接口。它必须确定如何构造一个满足该接口的对象。我没有构造一个实现该接口的具体对象,也没有构造一个 Decimal。\n(更新:这篇文章进一步让我相信我的直觉...https://jameshenry.blog/typescript-classes-vs-interfaces/)\n官方文档(以及我观察到的每一个非官方来源)都演示了它与“简单”类型(特别是 number 和 string)配合使用的情况,我的直觉告诉我“这是有道理的”,因为一个 JSON 对象可以有简单的字符串和简单的数字。\n我是否忽略了显而易见的东西?还是直接映射到更复杂的类类型是不可能的?\n如果是不可能的,你通常是如何处理的?我寻找了“最佳实践”模式,但结果不尽如人意。\n同样,我的直觉(仅仅是我的直觉)告诉我,我应该在一个类内部有一个处理 API 请求的私有方法,并返回一个 Observable(调用者将会订阅)以提供一个复杂对象类型(例如一个 User 类的数组,它们具有与用户相关的方法):\nclass Service {\n // 返回一个复杂对象类型的 Observable,以供其他地方使用\n doSomethingCool(): Observable {\n return this._http\n .get(\"url://somewhere\");\n }\n}\n这样做有意义吗?谢谢。

0
0 Comments

Angular中的HttpClient的get()方法可以使用泛型来指定返回的数据类型。通常情况下,这些泛型类型是简单的属性类型,比如字符串或数字。然而,有时候我们想要使用非简单的属性类型,例如自定义的对象。

在上面的代码示例中,开发者遇到了这样的问题:他想要从https://jsonplaceholder.typicode.com/users这个API获取数据,并将其赋值给组件中的data属性。然而,由于返回的数据类型不是简单的属性类型,他无法直接指定泛型类型。

为了解决这个问题,开发者尝试了一种方法:不定义模型,直接使用Observable<any>作为泛型类型。这样做的好处是不需要在多个地方定义和维护模型,但是也存在一些不方便之处。

然而,通过这种方法,开发者成功地从API中获取到了数据,并在模板中使用了它。他使用了ngFor指令来遍历data属性,并在模板中显示了每个item的name属性。

以下是完整的组件代码:

import { Component } from '/core';
import { HttpClient } from '/common/http';
import { Observable, throwError } from 'rxjs';
export class ProductListComponent {
  data: any;
  constructor(private http: HttpClient) {
  }
  getdata() {
    this.http
      .get>('https://jsonplaceholder.typicode.com/users')
      .subscribe(
        data => {
          this.data = data;
        },
        error => {
          console.log(error);
        }
      );
  }
}

至于解决方法,开发者并没有提及其他可行的方法。然而,他可以考虑以下几种解决方案:

1. 定义一个模型:开发者可以创建一个模型类,用来表示从API返回的数据结构。然后,他可以在get()方法的泛型类型中使用这个模型类,以便正确地解析返回的数据。

2. 使用any类型:开发者也可以使用any类型作为泛型类型,来接收任意类型的返回数据。这样做的好处是灵活性较高,但是也失去了类型安全检查的优势。

无论采用哪种解决方法,开发者都需要根据实际情况选择合适的方式来处理非简单属性类型的返回数据。

以上是针对问题"Can Angular `HttpClient` `.get()` generics have non-simple property types? (e.g. other than `string` or `number`)"的原因和解决方法的整理。

0
0 Comments

Angular的HttpClient.get()方法的泛型是否可以有非简单属性类型(例如除了string或number之外的其他类型)?

这个问题的出现原因是,在使用Angular的HttpClient.get()方法时,泛型只能接受简单的属性类型,无法接受复杂的属性类型,比如Date类型。这导致在处理返回的数据时,无法将复杂属性类型转换为真正的类型。

解决方法是通过创建一个构造函数来实现属性类型的转换。在构造函数中,可以接受一个Partial对象作为参数,然后使用Object.assign()方法将该Partial对象的属性值复制给当前对象。如果属性类型不是Date类型,则将其转换为Date类型。

具体代码如下:

export class Product {
    public name: string;
    public description: string;
    public viewPublic: boolean;
    public validFrom?: Date;
    public validTo?: Date;
    public _id?: string;
    /**
     * Constructor to help solidification of this model when a HttpClient.Get() call is made.
     */
    public constructor(init?: Partial) {
        Object.assign(this, init);
        if (init.validFrom !== null && init.validFrom instanceof Date === false) {
            this.validFrom = new Date(this.validFrom.toString());
        }
        if (init.validTo !== null && init.validTo instanceof Date === false) {
            this.validTo = new Date(this.validTo.toString());
        }
    }
}

通过这种方式,可以在调用HttpClient.get()方法时,将返回的数据转换为真正的对象,并且属性类型是正确的。同时,可以使用map()方法对返回的数据进行进一步处理,将其转换为真正的对象数组。

return this._http
    .get(this.productApiUrl)
    .map(res => this.solidfyAll(res, Product));

通过以上方法,可以解决Angular的HttpClient.get()方法的泛型无法处理非简单属性类型的问题,实现了属性类型的转换。这样,在使用HttpClient.get()方法时,可以更方便地处理复杂的属性类型。

0
0 Comments

问题的出现的原因是:Angular的HttpClient的get()方法默认返回的是JSON数据,而根据JSON数据类型的定义,它只能是字符串、数字、对象(JSON对象)、数组、布尔值或null。所以,对于除了字符串或数字之外的非简单属性类型,无法直接使用get()方法获取。

解决方法是:可以先将返回的Response对象映射为JSON格式,然后再进行后续操作。可以使用RxJS中的map()方法来实现映射,需要先导入rxjs库。具体代码如下:

import "rxjs/add/operator/map";
....
class Service {
    doSomethingCool(): Observable {
        return this._http
            .get("url://somewhere");
            .map((response:Response) => response.json() as IMyDataItem);
    }
}

需要注意,在使用map()方法之前需要先导入rxjs库。

另外,通过讨论可以得知,该问题可能是因为使用的是Angular版本<=4.2的旧的http库。如果希望解决该问题,可以考虑使用Angular版本>=4.3的新的HttpClient库。需要注意的是,旧的http库默认返回的是JSON格式的数据,而新的HttpClient库默认返回的也是JSON格式的数据。

以上是该问题的出现原因和解决方法的整理。通过映射为JSON格式可以解决无法直接获取非简单属性类型的问题。这样可以更方便地对返回的数据进行操作和处理。

0