首页 > 解决方案 > 元素数组不会被接口填充

问题描述

我在 Angular 中提出以下请求并将响应保存在变量中:

conversations: Conversation[];

// ChatService
getConversations() {
    return this.http.get<Conversation[]>('/chat/conversations');
}

this.chatService.getConversations().subscribe(
    (response: Conversation[]) => this.conversations = response
);

这是来自服务器的 JSON 数据:

[  
   {  
      "chatRoomId":"096b8be1-2411-4cb1-94e0-ed96c51c23d8",
      "name":"Bar",
      "profilePicture":"...",
      "conversation":[  
         {  
            "name":"Bar",
            "message":"Hello!",
            "createdAt":"2018-09-30T06:50:49.000+0000"
         },
         {  
            "name":"Foo",
            "message":"Hi",
            "createdAt":"2018-09-30T11:49:05.000+0000"
         }
      ]
   }
]

打字稿模型:

export interface Conversation {
  chatRoomId: string;
  name: string;
  profilePicture: string;
  conversation: ChatMessage[]
}

export interface ChatMessage {
  name: string;
  message: string;
  createdAt: string;
}

问题:

如果我在控制台中输出变量,则对话 ( conversation: ChatMessage[]) 是一个空数组元素。

如果我提出请求this.http.get<any>('...'),对话将按预期存储。

标签: arraysjsonangulartypescript

解决方案


有几种方法可以做你想做的事情,但根据我的经验,使用这个库是最简单的:https ://github.com/typestack/class-transformer

以下是它在您的情况下的工作方式。首先,我会将您的接口更改为 Typescript 类。

import { Type } from 'class-transformer';

export class Conversation {
    chatRoomId: string;
    name: string;
    profilePicture: string;

    @Type(() => ChatMessage)
    conversation: ChatMessage[]

    constructor(args: Conversation) {
      Object.assign(this, args);
    }
}

export class ChatMessage {
    name: string;
    message: string;
    createdAt: string;

    constructor(args: ChatMessage) {
      Object.assign(this, args);
    }
}

与这些接口相比,一些事情发生了变化::

  1. 装饰器的使用@Type来自 class-transformer 模块。这允许您转换嵌套对象。这是文档:https ://github.com/typestack/class-transformer#working-with-nested-objects
  2. 我们添加了一个constructor允许您创建这些类的实例并将属性传递给它们各自类型的属性。看看这篇文章将 httpClient 答案转换为模型对象 [Angular 6],因为它更清楚地说明了这里发生的事情。

然后在您的服务中,这就是您的代码更改的方式:

import { plainToClass } from 'class-transformer';    

conversations: Conversation[];

// ChatService
getConversations() {
    return this.http.get<Conversation[]>('/chat/conversations');
}

this.chatService.getConversations().subscribe(
    (response: Conversation[]) => {
        this.conversations = plainToClass(Conversation, response) as Conversation[]
    }
);

plainToClass将获取原始 JSON 响应并将其转换为会话类的实例。如果您 console.log out,this.conversations您将看到它返回一个对话数组,每个对话都有一个名为conversationsChatMessage 的数组属性。


推荐阅读