【问题标题】:Angular 5 models httpClient type castingAngular 5 模型 httpClient 类型转换
【发布时间】:2018-04-10 21:55:48
【问题描述】:

我在成分.model.ts 中声明了一个模型

export class Ingredient {
 constructor(private name: string, public amount: number) {}

 getName() { return this.name }
}

在 ingredients.service.ts 中,如果我以这种方式获取它们:

httpClient.get<Ingredient>(url).subscribe(
 (igredient) => {
   console.log(igredient.getName());
 });

它在控制台中给出错误,例如“属性igredient中没有方法getName”。

此外,每当我尝试声明属性类型 Category[] 时,它都会失败,但 Array 似乎工作正常。

编辑: 我想提供更多信息。

给定 Igredient 模型和以下 JSON 结构:

{
 name: "Apple",
 amount: "5",
 created_at: "date",
}

甚至没有调用 Igredient 构造函数,因此不会解析 GET 有效负载。

【问题讨论】:

  • 这是打字稿,不是java!尝试使用真正的访问器typescriptlang.org/docs/handbook/classes.html#accessors
  • Angular 的文档明确指出,可以通过 HttpClient 进行自动转换。
  • 您实际上是在取回一种成分还是在获得 json 响应?
  • 我收到一个带有成分结构的 json 响应

标签: httpclient models angular5


【解决方案1】:

您需要使用属性,而不是方法。返回的对象实际上是一个 json 对象,并且没有“getName()”方法之类的东西(尽管您努力添加了类型信息)。试试这样的:

export interface Ingredient {
    strin: string,
    amount: number,
    created_at: string
}


httpClient.get<Ingredient>(url).subscribe(
     (igredient) => {
          console.log(igredient.amount);
});

编辑:您需要根据预期的 json 对象提供类型信息。如果返回的json对象有attributes、strin、amount、created_at,那么需要定义一个与期望的json对象兼容的类型。

【讨论】:

  • 那么自定义成分类有什么用? PS:如果我在构造函数中插入一个调试器,它甚至不会被调用!
  • ingredient.name 不会抛出错误,因为您定义了一个类型 Ingredient
  • 好的,谢谢。我不知道。请看编辑,我仍然有问题。
  • @zangarmarsh 我没有在您预期的 json 返回对象中看到任何“名称”。更新了答案。请注意,您并不是真正“铸造”或“构造”一个​​对象。您只是向编译器提供类型信息,以便您可以在代码中使用像 ingredient.amount 这样的表达式。
  • 哦,好吧,我以为对象会被构造函数解析。谢谢你的信息!
【解决方案2】:

在 Angular 5 中,您可以这样做:

export interface Deserializable<T> {
    deserialize(input: any): T;
  }

export class Ingredient implments Deserializable<Ingredient>{
constructor(private name: string, public amount: number) {}

deserialize(input: any): Project {
    Object.assign(this, input);
    // do nested thing here -pop arrays of nested objects and create them
    }
    return this;
  }

现在为您服务:

  httpClient.get<Ingredient>(url).pipe(map(elem=>this.foo(elem)))
 .subscribe((igredient) => {console.log(igredient.getName());
   });

foo(ingredient:Ingrdient){
 var i = new Ingridiant().desrialize(ingredient)
}

在地图之后,您将拥有 Ingradient 类,而不是对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-06
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    相关资源
    最近更新 更多