Json为打字稿对象。继承
问题描述:
我有三个类Json为打字稿对象。继承
class Device{
name:string;
}
class Mobile extends Device{
number:string;
}
class Computer extends Device{
macAddress:string;
}
和JSON
[{
'name':'mobile1',
'number':'600 600 600',
'class':'Mobile'
},{
'name':'computer',
'macAddress:'123123123',
'class':'Computer'
}]
是有可能使用某种装饰/或任何其他的获得与正确的对象类型的设备清单。 我生产Json在我的网站,所以我还可以添加其他领域,改变结构,使打字稿对象列表corectly生成
我正在寻找任何解决方案没有成功。
问候, 阿德里安
答
我根据我的解决方案是什么安德烈亚斯写道:谢谢。 为了达到正确的解决方案,我使用了令人敬畏的库 json2typescript 。我的解决方案:
import {JsonObject, JsonProperty, JsonConverter, JsonCustomConvert, JsonConvert} from "json2typescript";
@JsonConverter
class DeviceConverter implements JsonCustomConvert<DeviceDto[]> {
// We receive the instance and just serialize it with the standard json2typescript method.
serialize(device: DeviceDto[]): any {
const jsonConvert: JsonConvert = new JsonConvert();
return jsonConvert.serialize(device);
}
// We receive a json object (not string) and decide
// based on the given properties whether we want to
// create an instance of Computer or Mobile.
deserialize(devicesInput: any): DeviceDto[] {
const jsonConvert: JsonConvert = new JsonConvert();
let devices: Array<DeviceDto> = new Array<DeviceDto>();
for (let device of devicesInput) {
if (device['type'] == 'mobile') {
let temp:MobileDeviceDto=jsonConvert.deserialize(device, MobileDeviceDto)
devices.push(temp);
} else if (device['type'] == 'rpi') {
devices.push(jsonConvert.deserialize(device, RaspberryPiDeviceDto));
}
}
return devices;
}
}
@JsonObject
export class DevicesDto {
@JsonProperty("devices", DeviceConverter)
devices: DeviceDto[] = [];
}
@JsonObject
export class DeviceDto {
@JsonProperty("name", String)
name: string= undefined;
@JsonProperty("description", String)
description: string= undefined;
@JsonProperty("type", String)
type: string= undefined;
}
@JsonObject
export class MobileDeviceDto extends DeviceDto {
@JsonProperty("number", String)
number: string = undefined;
}
@JsonObject
export class RaspberryPiDeviceDto extends DeviceDto {
@JsonProperty("version", String)
version: string = undefined;
}
用法:
let jsonConvert: JsonConvert = new JsonConvert();
let devices: DeviceDto[] = jsonConvert.deserialize(data, DevicesDto).devices;
this.subjectDeviceList.next(data);
非常感谢你:)
答
我建议以下实现。请注意里面的意见。它可能包含一些错误,因为我实际上无法检查代码,所以可能需要做更多的工作。
基本思路:为了使组件中的代码变得简单,您应该将数组包装到一个对象中,这里称为JsonDevices。然后你可以编写一个自定义转换器,让魔法发生在转换器内部。
类
// Custom serializer/deserializer.
// You must implement serialize and deserialize methods
@JsonConverter
class DeviceConverter implements JsonCustomConvert<Device> {
// We receive the instance and just serialize it with the standard json2typescript method.
serialize(device: Device): any {
const jsonConvert: JsonConvert = new JsonConvert();
return jsonConvert.serialize(device);
}
// We receive a json object (not string) and decide
// based on the given properties whether we want to
// create an instance of Computer or Mobile.
deserialize(device: any): Device {
const jsonConvert: JsonConvert = new JsonConvert();
// We need the try/catch because of deserialize inside
try {
if (device.name && device.macAddress) {
const computer: Computer = new Computer();
computer.name = device.name;
computer.macAddress = device.macAddress;
return jsonConvert.deserialize(computer, Computer);
} else if (device.name && device.number)
const mobile: Mobile = new Mobile();
mobile.name = device.name;
mobile.number = device.number;
return jsonConvert.deserialize(mobile, Mobile);
}
} catch(e) {}
throw new TypeError();
}
}
@JsonObject
class JsonDevices {
@JsonProperty("devices", DeviceConverter)
devices: Device[] = [];
}
@JsonObject
class Device {
@JsonProperty("name", String)
name: string = undefined;
}
@JsonObject
class Mobile extends Device {
@JsonProperty("number", String)
number: string = undefined;
}
@JsonObject
class Computer extends Device {
@JsonProperty("macAddress", String)
macAddress: string = undefined;
}
使用
// Assume this is your incoming json
const jsonString: string = ("
[{
'name':'mobile1',
'number':'600 600 600',
'class':'Mobile'
},{
'name':'computer',
'macAddress:'123123123',
'class':'Computer'
}]
");
// Convert it to an JSON/JavaScript object
// In the current Angular 4 HttpClientModule API,
// you would get an object directly and you wouldn't
// bother with it anyway.
const jsonArray: any[] = JSON.parse(jsonString);
// Make sure the given array is added to an object
// having a device array
const jsonDevicesObject: any = {
devices: jsonArray;
}
// Now deserialize the whole thing with json2typescript:
const jsonConvert: JsonConvert = new JsonConvert();
const jsonDevices: JsonDevices = jsonConvert.deserialize(jsonDevicesObject, JsonDevices);
// Now all elements of jsonDevices.devices are of instance Mobile or Computer
+0
使用'Mobile | Computer'而不是'Device'作为提示可能会更聪明(甚至是必要的)? – andreas
嗨阿德里安,我觉得你的第三类应该被命名为 '计算机'。除此之外,您可以尝试将JSON对象解析为let:Mobile或Computer,然后查看它是否有效。 – cdslijngard
谢谢,现在正确 – Adrian