如何将SignalR有效负载映射到TypeScript类?

时间:2018-11-29 08:01:08

标签: angular typescript signalr asp.net-core-2.1

我们正在使用signalR从服务器请求使用的cpu和ram:

// create connection
let hubConnection = new signalR.HubConnectionBuilder().withUrl("/MyUrl").build();

// response message
hubConnection.on("ReceiveMessage", (pMessage: string) => {

  // convert to json
  let lObj = JSON.parse(pMessage);
  let lServerResources = new ServerResources(lObj.cpu, lObj.ram);

  // do something with this result [...]
});

这是简单的ServerResources类:

// simple data class
export class ServerResources
{
  constructor(public cpu: string, public ram: string)
  {  }
}

问题:pMessage参数包含一个json字符串作为值,如:'{"cpu":"72%","ram":"2540MB"}',我们需要将其转换为javascript对象,然后映射到{{ 1}}类。我们要保存这两个步骤。我们想直接获得一个ServerResources对象。

我们尝试了以下方法。但这仍然是一个字符串:

ServerResources

Anyhow Angular通过泛型映射http请求的有效负载:

hubConnection.on("ReceiveMessage", (pMessage: ServerResources) => {
    // [...]
}

问题:我们如何将singnalR有效载荷自动映射到打字稿类?

1 个答案:

答案 0 :(得分:0)

我为hydrate TypeScript classes from JSON写了一个通用函数:

function hydrate<T>(constr: { new(...args: any[]): T }, data: string, strictMode: boolean = true, ...args: any[]): T {
    const obj = JSON.parse(data);
    const instance = new constr(...args);

    for (let key in obj) {
        if (!strictMode || instance.hasOwnProperty(key)) {
            instance[key] = obj[key];
        }
    }

    return instance;
}

以下是在您的特定情况下使用它的示例(我在类中添加了一个方法进行说明):

class ServerResources {
  constructor(public cpu: string, public ram: string)
  { }

  getSomething() {
    alert(this.cpu + ' ' + this.ram)
  }
}

const data = `{ "cpu": "SUPER-8", "ram": "FAST-SHEEP"}`;

const example = hydrate(ServerResources, data, false);

example.getSomething();