问题描述
我有这个代码.请注意,序列化只是将template_items属性重命名为template_items_attributes:
I have this code. Notice that the serialization is simply renaming the template_items property to template_items_attributes:
export class Template {
constructor(
) {}
public id: string
public account_id: string
public name: string
public title: string
public info: string
public template_items: Array<TemplateItem>
toJSON(): ITemplateSerialized {
return {
id: this.id,
account_id: this.account_id,
name: this.name,
title: this.title,
info: this.info,
template_items_attributes: this.template_items
}
}
}
export interface ITemplateSerialized {
id: string,
account_id: string,
name: string,
title: string,
info: string,
template_items_attributes: Array<TemplateItem>
}
在本地创建对象可以很好地工作,并且可以使用stringify调用toJSON()方法.
Creating an object locally works fine and stringify calls the toJSON() method.
但是,一旦我将该对象发送到API:
However, once I send that object to the API:
private newTemplate(name: string): Template {
let template = new Template();
template.name = name;
template.account_id = this._userService.user.account_id;
// next 5 lines are for testing that toJSON() is called on new obj
let item = new TemplateItem();
item.content = "Test"
template.template_items.push(item);
let result = JSON.stringify(template);
console.log('ready', result); // SHOWS the property changes
return template;
}
postTemplate(name: string): Observable<any> {
return this._authService.post('templates', JSON.stringify(this.newTemplate(name)))
.map((response) => {
return response.json();
});
}
它已保存并返回,但是从那时起,当我再次进行字符串化和保存时,它不会调用JSON().
It is saved and returned, but from that point on when I stringify and save again it does NOT call toJSON().
patchTemplate(template: Template): Observable<any> {
console.log('patching', JSON.stringify(template)); // DOES NOT CHANGE!
return this._authService.patch('templates' + `/${template.id}`, JSON.stringify(template))
.map((response) => {
return response.json();
});
}
为什么toJSON()仅在新对象上起作用?
Why does toJSON() only work on new objects?
推荐答案
实际上,您的问题与Angular或Typescript无关,这只是一些JavaScript以及序列化工作原理和为什么我们是否序列化对象.
In fact, your question has nothing to do with Angular or Typescript, it's just some JavaScript and the logic of how serialization work and why do we serialize objects.
我将该对象发送到API,保存并返回
I send that object to the API, save and return it
当您从API返回对象"时,您将返回解析为JSON序列化对象的字符串.然后,您将获得一个 plain JavaScript对象,而不是您的类的实例.
When you return an "object" from an API, you're returning a string which you parse as a JSON serialized object. Then you get a plain JavaScript object, not an instance of your class.
Object
原型没有toJSON
方法,即使有,它也不是您在Template
类中编写的方法,因此不会被调用.
Object
prototype in JavaScript does not have toJSON
method, and even if it had, it's not the method you've written inside the Template
class, so it won't be called.
您甚至不需要服务器调用即可复制它,只需这样做
You don't even need a server call to replicate this, just do
const obj = JSON.parse(JSON.stringify(new Template()))
obj.toJSON // undefined
您将看到obj
不是Template
的实例.它只是一个对象,恰好碰巧将所有字段都作为您的原始对象作为Template
实例制成,但它不是该类的实例.
And you'll see that obj
is not an instance of Template
. It's simply an object which simply happens to have all the fields as your original object made as a Template
instance, but it's not an instance of that class.