我使用NSwag为swagger API端点生成TypeScript类型和类。生成的类包含每个对象的.toJSON()
方法,在使用JSON.stringify()
将对象序列化为JSON时调用该方法。
序列化单个对象时一切正常,但是当我尝试序列化一个对象数组时,它会抛出一个奇怪的错误:
angular.js:14199 TypeError: Cannot create property 'code' on string '0'
at Dashboard.toJSON (App/models/api.js:785:34)
at JSON.stringify (<anonymous>)
并且触发它的代码非常简单:
console.log(JSON.stringify([
Dashboard.fromJS({
code: "1212312",
name: "tresads",
description: "some description"
}),
Dashboard.fromJS({
code: "1212312",
name: "tresads",
description: "some description"
})
]));
该课程的摘录:
export class Dashboard implements IDashboard {
code?: string | undefined;
...
constructor(data?: IDashboard) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(data?: any) {
if (data) {
this.code = data["code"];
...
}
}
static fromJS(data: any): Dashboard {
let result = new Dashboard();
result.init(data);
return result;
}
toJSON(data?: any) {
data = data ? data : {};
data["code"] = this.code;
...
return data;
}
clone() {
const json = this.toJSON();
let result = new Dashboard();
result.init(json);
return result;
}
}
明白为什么JSON.stringify()
使用&#34; 0&#34;调用toJSON()
方法参数β
答案 0 :(得分:1)
将使用一个参数调用方法toJSON
,该参数是分配this
的属性名称。从本质上讲,您感兴趣的价值不是那个参数,而是this
,它将被绑定到您可以转换的值。由于您使用数组调用stringify
,因此toJSON
将使用该数组的可枚举属性进行调用,即0
和1
,而this
将是相应的仪表板对象。
另外,我的印象是你可以很好地利用Object.assign
将属性从一个对象复制到另一个对象,这基本上就是你在构造函数的for
循环中所做的。
所以这就是你如何做到的。我删除了打字稿装饰并使用了纯JavaScript,但原理保持不变:
class Dashboard {
constructor(data) {
// Object.assign does essentially what you want with the loop:
Object.assign(this, data);
}
init(data) {
return Object.assign(this, data);
}
static fromJS(data) {
return new Dashboard(data);
}
toJSON(key) {
// `key` is the key/index of the property in the parent object.
// That probably is of no interest to you. You need `this`.
// Extract properties into plain object, and return it for stringification
return Object.assign({}, this);
}
clone() {
return new Dashboard(this);
}
}
console.log(JSON.stringify([
Dashboard.fromJS({
code: "1212312",
name: "tresads",
description: "some description"
}),
Dashboard.fromJS({
code: "1212312",
name: "tresads",
description: "some description"
})
]));
&#13;
实际上,在给定的示例中,您根本不需要toJSON
,因为Dashboard实例的属性是可枚举的,因此无论如何它们都将被字符串化。如果由于某种原因你需要它来进行某种转换,那么你当然还需要包含该转换的逻辑,因为Object.assign
只是一个简单的副本。