網站搜尋

json - 元素陣列不會被介面填充


我在 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"
         }
      ]
   }
]

TypeScript 模型:

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>('...') 發送請求,對話就會按預期被存儲。

答案#1

有幾種方法可以做到你想做的事,但根據我的經驗,使用這個函式庫是最簡單的: 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 回應轉換為你的 Conversation 類別的實例。如果你對 this.conversations 使用 console.log,你會看到它返回的是一個 Conversations 的陣列,每個 Conversations 都有一個名為 conversations 的陣列屬性,其類型為 ChatMessage。