我从AJAX调用REST服务器收到一个JSON对象。该对象具有与我的TypeScript类匹配的属性名称
初始化它的最佳方法是什么?我认为这行不通,因为类(和JSON对象)具有作为对象列表的成员和作为类的成员,而这些类具有作为列表和/或类的成员。
但是我更喜欢一种查找成员名称并在其间进行分配,创建列表并根据需要实例化类的方法,因此,我不必为每个类中的每个成员编写明确的代码(有很多!)
这些是一些快速快照,它们显示了几种不同的方式。它们绝不是“完整的”,作为免责声明,我认为这样做不是一个好主意。代码也不是很干净,因为我只是很快地将它们键入在一起。
还要注意:可反序列化的类当然需要具有默认的构造函数,就像我知道任何反序列化的所有其他语言一样。当然,如果您调用不带参数的非默认构造函数,则Javascript不会抱怨,但是该类最好为此做准备(此外,它并不是真正的“打字方法”)。
这种方法的问题主要是,任何成员的名称都必须与其类匹配。这会自动将您限制为每个班级一名相同类型的成员,并破坏了一些良好实践的规则。我强烈建议您这样做,但请在此处列出,因为这是我编写此答案时的第一个“草稿”(这也是为什么名称为“
Foo”等的原因)。
module Environment {
export class Sub {
id: number;
}
export class Foo {
baz: number;
Sub: Sub;
}
}
function deserialize(json, environment, clazz) {
var instance = new clazz();
for(var prop in json) {
if(!json.hasOwnProperty(prop)) {
continue;
}
if(typeof json[prop] === 'object') {
instance[prop] = deserialize(json[prop], environment, environment[prop]);
} else {
instance[prop] = json[prop];
}
}
return instance;
}
var json = {
baz: 42,
Sub: {
id: 1337
}
};
var instance = deserialize(json, Environment, Environment.Foo);
console.log(instance);
为了摆脱选项#1中的问题,我们需要某种有关JSON对象中节点类型的信息。问题在于,在Typescript中,这些都是编译时构造,我们在运行时需要它们-
但是运行时对象只是在设置它们之前才意识到它们的属性。
一种方法是让类知道其名称。不过,您也需要在JSON中使用此属性。实际上,您 只 需要在json中使用它:
module Environment {
export class Member {
private __name__ = "Member";
id: number;
}
export class ExampleClass {
private __name__ = "ExampleClass";
mainId: number;
firstMember: Member;
secondMember: Member;
}
}
function deserialize(json, environment) {
var instance = new environment[json.__name__]();
for(var prop in json) {
if(!json.hasOwnProperty(prop)) {
continue;
}
if(typeof json[prop] === 'object') {
instance[prop] = deserialize(json[prop], environment);
} else {
instance[prop] = json[prop];
}
}
return instance;
}
var json = {
__name__: "ExampleClass",
mainId: 42,
firstMember: {
__name__: "Member",
id: 1337
},
secondMember: {
__name__: "Member",
id: -1
}
};
var instance = deserialize(json, Environment);
console.log(instance);
如上所述,类成员的类型信息在运行时不可用-除非我们使它可用。我们只需要对非原始成员执行此操作,我们很好:
interface Deserializable {
getTypes(): Object;
}
class Member implements Deserializable {
id: number;
getTypes() {
// since the only member, id, is primitive, we don't need to
// return anything here
return {};
}
}
class ExampleClass implements Deserializable {
mainId: number;
firstMember: Member;
secondMember: Member;
getTypes() {
return {
// this is the duplication so that we have
// run-time type information :/
firstMember: Member,
secondMember: Member
};
}
}
function deserialize(json, clazz) {
var instance = new clazz(),
types = instance.getTypes();
for(var prop in json) {
if(!json.hasOwnProperty(prop)) {
continue;
}
if(typeof json[prop] === 'object') {
instance[prop] = deserialize(json[prop], types[prop]);
} else {
instance[prop] = json[prop];
}
}
return instance;
}
var json = {
mainId: 42,
firstMember: {
id: 1337
},
secondMember: {
id: -1
}
};
var instance = deserialize(json, ExampleClass);
console.log(instance);
__2016年1月3日 更新:
正如@GameAlchemist在注释想法,实现中指出的那样,从Typescript
1.7开始,可以使用类/属性装饰器以更好的方式编写以下描述的解决方案。
序列化总是一个问题,我认为最好的方法就是最短的方法。在所有选项中,这是我想要的,因为该类的作者完全控制了反序列化对象的状态。如果我不得不猜测,我会说所有其他选择迟早都会给您带来麻烦(除非Javascript提出了一种本机处理方式)。
的确,以下示例并未体现灵活性。它确实确实只是复制了类的结构。不过,您必须在这里记住的区别是,该类具有完全控制权,可以使用它想要控制整个类的状态的任何JSON(您可以计算事物等)。
interface Serializable<T> {
deserialize(input: Object): T;
}
class Member implements Serializable<Member> {
id: number;
deserialize(input) {
this.id = input.id;
return this;
}
}
class ExampleClass implements Serializable<ExampleClass> {
mainId: number;
firstMember: Member;
secondMember: Member;
deserialize(input) {
this.mainId = input.mainId;
this.firstMember = new Member().deserialize(input.firstMember);
this.secondMember = new Member().deserialize(input.secondMember);
return this;
}
}
var json = {
mainId: 42,
firstMember: {
id: 1337
},
secondMember: {
id: -1
}
};
var instance = new ExampleClass().deserialize(json);
console.log(instance);
问题内容: 嗨,我是新手,想尽办法。如何从json对象初始化结构。我不知道该怎么办。 {“用户”:{“名称”:“ cruskuaka”,“电子邮件”:“ cristlika@gmail.com”,“电话号码”:“ 018833455”},“地址”:{“房屋”:“ 100”,“街道“:” B“,”镇“:{” town_id“:” 1“,” town_name“:”高威市中心“},” city“:{”
我在使用Mockito进行单元测试初始化对象时遇到了一些困难 这是我的测试代码 要测试的代码 RecTangleService、CircleService和SquareService用注释我尝试了很多选项,最终得出结论。我没有得到我错在哪里。我试着在网上搜索了很多地方,但找不到任何帮助。
问题内容: 我只是看了这个SO Post: 但是,哥伦比亚大学教授的笔记按以下方式进行。请参阅第9页。 哪种方法正确?他们似乎在说不同的话。 特别是在注释版本中没有。 问题答案: 这根本不会在Java中编译(因为您正在将数组类型的值分配给非数组类型的变量): 被以下错误拒绝(另请参见:http : //ideone.com/0jh9YE): 要进行编译,请声明其类型,然后在其上循环:
我预计Spring会通过将属性“property.key”设置为“property_value”来初始化StorageConfiguration对象。 但是,我得到以下异常 org.springframework.beans.factory.beanCreationException:创建类路径资源[applicationContext.xml]中定义的名为“storage”的bean时出错:在设
我希望从typescript