我们对我们的服务有各种Http调用,它们返回对象的集合。在我们的角度应用程序中,打字稿将它们解释为适当的类型(如果指定),例如Person:
export class Person{
public firstName: string;
public lastName: string;
public salutation: string;
}
比方说,我希望能够轻松地为此用户构建问候语字符串,但是我想成为一名优秀的程序员,并且一次执行而不是多次执行。因此,我创建了一个将获取它的吸气剂:
export class Person{
public firstName: string;
public lastName: string;
public salutation: string;
public get greeting(): string {
return salutation + " " + firstName + " " + lastName;
}
}
但是,当打字稿反序列化时,它缺少greeting属性的原型(将其设置为undefined)。我发现打字稿正在将JSON对象映射到它具有的类,并且映射的对象上不存在任何缺少的字段/属性(如果调用,则返回undefined)。解决此问题的最佳方法是什么?
作为我们如何调用服务的示例:
this.authHttp.post(this.url, user, params).then(
(res: Person) => {
console.log(res);
console.log(res.greeting);
}
);
答案 0 :(得分:1)
您必须创建一个包含对象所有字段的复制构造函数:
public static final ResourceBundle QUERY_EXCEL = ResourceBundle.getBundle("ConsultaExcel");
String query=QueryManager.QUERY_EXCEL.getString("SQL.SELECT.consultarDatos");
现在您可以做
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
当然有很多变体。你可以做
http.post(...)
.pipe(map(res => new Person(res.firstName, res.lastName)))
.subscribe(...);
例如,避免再次手动分配值。或想出其他任何您想写的方式。归根结底,这就是您实际上需要创建类的 instance ,而不是仅将类类型用作类型。
答案 1 :(得分:1)
您巧用巧巧的方式 ,因为您正在访问的属性名称也由.post
的响应提供。实际上,在将tsc
转换为JavaScript源的命令之后,不再使用TypeScript。因此,您将在运行时丢失所有类型检查。
如果您要对此任务进行硬编码,就像这样:
let me: Person = { firstName: 'Ian', lastName: 'MacDonald', salutation: 'Hello.' };
您将在尝试创建JavaScript时收到TypeScript错误。
Property 'greeting' is missing in type
'{ firstName: string; lastName: string; salutation: string; }'
but required in type 'Person'.ts(2741)
对于您在类中定义的任何函数,也会出现相同的错误。这是因为{ ... }
不是您的类型;它只有明确定义的内容。服务器响应的结果将遵循相同的分配规则,但是直到运行时该问题才会出现(因为数据不存在)。
我建议在尝试使用服务器响应之前,先使用管道为自己构造类的实例,以便在首次尝试访问.save()
时,可以在第一次联系时捕获任何错误,而不是在10秒钟后发现错误。不存在的动作。
.post(...).pipe(map((incoming: any) => {
let person: Person = new Person();
person.firstName = incoming.firstName;
person.lastName = incoming.lastName;
person.salutation = incoming.salutation;
return person;
});
答案 2 :(得分:0)
HTTP调用的响应不会生成Person类的对象。响应实际上是一个纯JavaScript对象,显然没有Person类的greeting()方法。
为了解决该问题,您可以应用以下代码:
http.post(...)
.pipe(map(res => Object.assign(new Person(), res)))
.subscribe(...);
Object.assign(new Person(),res)函数会将所有res值复制到Person实例。在此映射之后,您将拥有一个真实的Person实例,其属性值从http调用返回的资源中复制。