我有硬编码的类来表示我的Aurelia应用程序中的模型。这是一个模型' PostEdit':
var _postID = Symbol();
var _title = Symbol();
var _text = Symbol();
export class PostEdit {
constructor(postEdit) {
this[_postID] = postEdit.postID;
this.title = postEdit.title;
this.text= postEdit.text;
}
get postID() { return this[_postID]; }
get title() { return this[_title]; }
set title(val) { this[_title] = val; }
get text() { return this[_text]; }
set text(val) { this[_text] = val; }
}
操作对象后,我需要PUT
并POST
将其返回给服务器。但看起来Aurelia
HttpClient
发送一个空的JSON
字符串({}
)。调查一下,将ES6类转换为Symbols
时似乎忽略了JSON
。
如何将所有属性转换为JSON
字符串以提交回服务器?
答案 0 :(得分:17)
我假设您正在使用符号来保持数据的私密性,但这意味着如果您希望JSON表示中包含这些数据,您将不得不经历一些额外的步骤。
以下是使用模型上的toJSON
明确导出您关注的属性的示例
export class PostEdit {
// ...
toJSON() {
return {
postID: this.postID,
title: this.title,
text: this.text
};
}
}
或者
export class PostEdit {
// ...
toJSON() {
let {postID, title, text} = this;
return {postID, title, text};
}
}
在您的实例上调用JSON.stringify
时,它会自动调用toJSON
答案 1 :(得分:6)
为您的类提供一个返回字符串化对象的toJSON
方法:
export class PostEdit {
constructor(postEdit) {
this[_postID] = postEdit.postID;
this.title = postEdit.title;
this.text = postEdit.text;
}
get postID() { return this[_postID]; }
get title() { return this[_title]; }
set title(val) { this[_title] = val; }
get text() { return this[_text]; }
set text(val) { this[_text] = val; }
toJSON() {
return {
postId: this.postId,
title: this.title,
text: this.text
};
}
}
JSON.stringify
会自动调用该内容,并将结果替换为您的实例。
此外,您可能希望在类中添加fromJSON
方法,以便在JSON.parse
期间恢复实例。在你的情况下这是微不足道的:
static fromJSON(obj) {
return new this(obj);
}
但在其他课程中你可能需要更复杂的东西。
答案 2 :(得分:4)
更多动态解决方案使用此:
export class MeMe(){
toJSON() {
return Object.getOwnPropertyNames(this).reduce((a, b) => {
a[b] = this[b];
return a;
}, {});
}
}
或者您可以使用我的json-decorator:)
import json from "json-decorator";
@json("postID") // pass the property names that you want to ignore
export class MeMe(){
// ...
}
答案 3 :(得分:3)
基于符号的私有变量是ES6中封装的重要配方。 JS中的封装很少被证明是合理的,但这些是在这里引起问题的访问器(而不是符号)。
ES6课程中的访问者为prototype methods。因此,属性不是在实例上定义,而是在原型上定义,它是不可枚举的。它可以在转换后的代码中看到,也可以通过检查
来查看postEditInstance.hasOwnProperty('postID') === false
Object.getPrototypeOf(postEditInstance).hasOwnProperty('postID') === true
Object.getPrototypeOf(postEditInstance).propertyIsEnumerable('postID') === false
另一方面, JSON.stringify
序列化对象的only own enumerable properties。
解决方案是使用toJSON方法根据所需条件序列化对象。或者在模型的存取器上使用奥卡姆剃刀,特别是如果它们在那里不重要的话。
答案 4 :(得分:0)
我希望使用Object.assign
我在将类分配给对象的类上使用它的初步观点。这为chrome中的_json
创建了一个无限循环。不好的主意。
class test {
constructor() {
this._json = {type: 'map'};
Object.assign(this, this._json);
}
toJSON(){
Object.assign(this._json, this);
return this._json;
}
}
我必须排除_json
变量,所以我迭代了类变量以排除它。
class test2 {
constructor() {
this._json = {type: 'map'};
Object.assign(this, this._json);
}
toJSON(){
Object.assign(this._json, {
conv() {
let ret = {};
for(let i in this )
{
if(i !== '_json')
ret[i] = this[i];
}
return ret;
}
} );
return this._json;
}
}
但即使没有_json
if(i !== '_json')
也会被忽略
尚未对它进行全面测试,但我认为这将是一个很好的分享。