【问题标题】:How to cast to Angular Model variables in httpClient/Observable/Map or whatever?如何在 httpClient/Observable/Map 或其他什么中转换为 Angular 模型变量?
【发布时间】:2018-12-12 14:29:37
【问题描述】:

因为我是 Angular/Typescript 的新手,我仍然有一些基本问题,但找不到合适的答案。如何接收或转换正确的值类型?

我已经定义了一个简单的模型:

export class Message {
    ID:                 number;
    mode:               string;
    senderID:           number;
    receiverID:         number;
    marked:             boolean;
    subject:            string;
}

现在我通过 message.service 从服务器获取数据,例如:

getMessages(): Observable<Message[]> {
    return this.restService.get('/message/list/' + this.owner)
}

在我的组件中,我通过以下方式读取值:

this.messageService.getMessages().subscribe((messages:Message[]) => {
    this.objectlist = messages
}

我需要和期望的是消息元素的真实数据类型,但一切都是 String。为什么没有布尔值数字

我也玩过 pipe() 和 map(),但我无法进行类型转换。

我做错了什么?我希望有人能帮我一把。提前谢谢。

【问题讨论】:

  • 确保服务器返回布尔值
  • 服务器返回一个 JSON 对象字符串,默认情况下所有编号的值都是字符串...布尔值返回为“0”或“1”
  • 你需要从服务器返回数字作为数字
  • 为什么?为什么我不能像之前在 JS 中那样在 map() 函数中转换从服务器返回的值?
  • @LarsHagen :最好从服务器正确获取。但如果你愿意,你绝对可以做一个地图和类型转换。当你 map() 时你得到了什么?

标签: angular typescript casting type-conversion observable


【解决方案1】:

TypeScript 只是 javascript 的一个打字层。因此,您不能仅通过定义类型来神奇地将一个值转换为另一个值。您确实必须对类型进行硬编码。在你的情况下:

getMessages(): Observable<Message[]> {
  return this.restService.get('/message/list/' + this.owner).pipe(
    map((messages) => messages.map((message) => ({
      ...new Message(), ...message, ...{
        ID: parseInt(message.ID),
        senderID: parseInt(message.senderID),
        receiverID: parseInt(message.receiverID),
        marked: message.marked === '1'
      }
    }))
  )
}

这确保返回的对象确实是 Message 类的数组。您还可以考虑使用特殊的装饰器,以确保在创建类时获得正确的类型:

export class Message {
    @IsNumber()
    ID:                 number;
    mode:               string;
    @IsNumber()
    senderID:           number;
    @IsNumber()
    receiverID:         number;
    @IsBoolean()
    marked:             boolean;
    subject:            string;
}

您可以使用一些第三方库,或者自己实现它们。

然后您可以将上面的代码更改为:

messages.map((message) => ({...new Message(), ...message))

【讨论】:

  • 您好 PierreDuc,感谢您提供的示例。我记得 Typescript 将根据它们的定义确保类型是正确的。我在上面试过你的例子。我之前有什么要导入的吗,因为 @IsNumber() 和 @IsBoolean() 似乎不存在(TS2552:找不到名称“IsNumber”。您的意思是“数字”吗?)
  • 是的,装饰器是我做的,但是你可以创建自己的装饰器,如果你有很多来自后端的数据结构,这是确保它们是正确的类型。就像我提到的,还有一些第三方库提供这些。除此之外,你告诉 TypeScript 一个对象会有什么类型。如果它来自 API 调用,您必须确保 API 发送正确的格式
  • 我尝试了您的两个示例,但均无效。类型转换不起作用。在数据可用之前调用装饰器,因此状态始终未定义。
  • 装饰器应该将属性转换为settergetter函数,其中setter将输入转换为正确的类型并将其存储在_ID属性中,getter得到它来自_ID 属性。尽管如此,第一个示例应该可以工作。如果没有,那么这意味着您的后端实际上并没有返回对象数组。
猜你喜欢
  • 2021-09-05
  • 2018-11-02
  • 1970-01-01
  • 2023-03-10
  • 2018-04-24
  • 2021-05-01
  • 2021-11-10
  • 1970-01-01
  • 2021-02-19
相关资源
最近更新 更多