Angular4-为什么自定义toJSON()只在新对象上被调用?

Angular4-为什么自定义toJSON()只在新对象上被调用?,json,angular,stringify,Json,Angular,Stringify,我有这个密码。请注意,序列化只是将template\u items属性重命名为template\u items\u属性: export class Template { constructor( ) {} public id: string public account_id: string public name: string public title: string public info: string public template_items: Ar

我有这个密码。请注意,序列化只是将template\u items属性重命名为template\u items\u属性:

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>
}
导出类模板{
建造师(
) {}
公共id:string
公共帐户\u id:字符串
公共名称:字符串
公共标题:字符串
公共信息:字符串
公共模板\u项:数组
toJSON():ITemplateSerialized{
返回{
id:this.id,
帐户id:this.account\u id,
姓名:this.name,
标题:这个,
info:this.info,
模板\u项\u属性:this.template\u项
}
}
}
导出接口ITemplateSerialized{
id:string,
帐户id:string,
名称:string,
标题:字符串,
信息:字符串,
模板\u项\u属性:数组
}
在本地创建对象工作正常,stringify调用toJSON()方法

但是,一旦我将该对象发送到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();
      });
  }
private newTemplate(名称:string):模板{
让模板=新模板();
template.name=名称;
template.account\u id=此。\u userService.user.account\u id;
//接下来的5行用于测试在新obj上调用toJSON()
let item=new TemplateItem();
item.content=“测试”
模板。模板\项目。推送(项目);
让result=JSON.stringify(模板);
console.log('ready',result);//显示属性更改
返回模板;
}
postTemplate(名称:string):可观察{
返回此。\u authService.post('templates',JSON.stringify(this.newTemplate(name)))
.map((响应)=>{
返回response.json();
});
}
它被保存并返回,但从那时起,当我再次字符串化并保存时,它不会调用toJSON()

patchTemplate(模板:模板):可观察{
console.log('patching',JSON.stringify(template));//不变!
返回此.u authService.patch('templates'+`/${template.id}`,JSON.stringify(template))
.map((响应)=>{
返回response.json();
});
}

为什么toJSON()只在新对象上工作?

事实上,你的问题与Angular或Typescript无关,只是一些JavaScript和序列化工作的逻辑,以及我们为什么序列化对象

我将该对象发送到API,保存并返回它

当您从API返回一个“对象”时,您将返回一个字符串,并将其解析为JSON序列化对象。然后得到一个普通的JavaScript对象,而不是类的实例

JavaScript中的
Object
prototype没有
toJSON
方法,即使有,也不是您在
模板
类中编写的方法,因此不会调用它

您甚至不需要服务器调用来复制它,只要这样做就可以了

const obj = JSON.parse(JSON.stringify(new Template()))
obj.toJSON // undefined

您将看到,
obj
不是
模板的实例。它只是一个对象,碰巧将所有字段作为原始对象制作成一个
模板
实例,但它不是该类的实例。

发布隐藏在后面的代码“一旦我将该对象发送到API,保存并返回它,从我字符串化并再次保存时起,它不会调用JSON()”,因为您实际上并没有将API响应转换回
模板
实例,而是将at作为一个常规对象,具有正确的属性,但没有任何方法。对于那些想进一步了解这一点的人,似乎应该使用装饰器和反射器。在此进行完整讨论:相关:。这似乎是一个很常见的误解。Typescript中有一个实验性的特性:谢谢。愚蠢的我认为Typescript中的类的行为类似于C#或Java类。我刚刚读了一些博客,现在我明白了。谢谢你的解释。
const obj = JSON.parse(JSON.stringify(new Template()))
obj.toJSON // undefined