打字稿,序列化类对象

Posted

技术标签:

【中文标题】打字稿,序列化类对象【英文标题】:Typescript, serialize class objects 【发布时间】:2015-05-26 16:17:07 【问题描述】:

如何将这些类序列化为 JSON?

从下面的示例中可以看出,JSON.stringify() 不会序列化 Cache_Backend_LocalStorage_TagThree 对象内的 Cache_Backend_LocalStorage_Tag 列表。

我错过了什么?

interface Cache_Backend_LocalStorage_Tag_Interface 
    _tag : string;
    _keys : string[];


class Cache_Backend_LocalStorage_Tag implements Cache_Backend_LocalStorage_Tag_Interface 

    public _tag : string;
    public _keys : string[];

    constructor(tag : string) 
        this._tag = tag;

        this._keys = [];
    

    public add(key : string) : void 
        this._keys.push(key);   
    

    public remove(key : string): boolean 
        // Get the index of the key
        var index = this._keys.indexOf(key, 0);

        // Check if we found the keys index
        if (index != undefined) 
           this._keys.splice(index, 1);

           return true;
        

        return false;
    

    public get tag(): string 
        return this._tag;
    

    public get keys(): string[] 
        return this._keys;
    


interface Cache_Backend_LocalStorage_TagThree_Interface 
    _tags : Cache_Backend_LocalStorage_Tag[];


class Cache_Backend_LocalStorage_TagThree implements Cache_Backend_LocalStorage_TagThree_Interface 

    public _tags : Cache_Backend_LocalStorage_Tag[];

    constructor(tags : Cache_Backend_LocalStorage_Tag[] = []) 
        this._tags = tags;
    

    public add(tag : Cache_Backend_LocalStorage_Tag) : void 
        this.tags[tag.tag] = tag;
    

    public get tags(): Cache_Backend_LocalStorage_Tag[] 
        return this._tags;
    

    public get(tagKey : string): Cache_Backend_LocalStorage_Tag 
        return this.tags[tagKey];
    

    public addKeyToTag(tagKey, key) 
        this.tags[tagKey].add(key);
    

    public removeKeyFromTag(tagKey, key) 
        // Get the tag
        var tag = this._tags[tagKey];

        // Check if we found the tag index
        if (tag != undefined) 
            return tag.remove(key);
        

        return false;
    

    public clear(tagKey : string): void 
        delete this._tags[tagKey];
    

    public static fromObject(object): Cache_Backend_LocalStorage_TagThree 
        return new Cache_Backend_LocalStorage_TagThree(object._tags);
    

问题:

var tagThree = new Cache_Backend_LocalStorage_TagThree();
tagThree.add(new Cache_Backend_LocalStorage_Tag("stores"));
tagThree.addKeyToTag("stores", "store5");
tagThree.removeKeyFromTag("stores", "store5");

//  "_tags":[]
console.log(JSON.stringify(tagThree));

//  _tags: [ stores:  _tag: 'stores', _keys: [Object]  ] 
console.log(tagThree);

【问题讨论】:

【参考方案1】:

原因

这是因为您将属性分配给数组,而数组属性不会包含在 JSON 序列化中。例如:

var a = [];
a["test"] = "some value";
JSON.stringify(a); // returns: []

你需要使用一个普通的对象:

var o = ;
o["test"] = "some value";
JSON.stringify(o); // returns: "test":"some value" 

解决方案

Cache_Backend_LocalStorage_TagThree_Interface 接口更改为使用dictionary like 对象:

interface Cache_Backend_LocalStorage_TagThree_Interface 
    _tags :  [tag: string] : Cache_Backend_LocalStorage_Tag; ;

然后更新所有将出现编译错误的代码区域以使用相同的类型。例如,改变:

constructor(tags : Cache_Backend_LocalStorage_Tag[] = []) 

收件人:

constructor(tags :  [tag: string] : Cache_Backend_LocalStorage_Tag;  = ) 

只是为了好玩 - 更改默认序列化行为(不推荐)

如果您真的想在当前设置下使用数组(我不确定为什么),您可以覆盖序列化的完成方式。为此,将toJSON 方法添加到Cache_Backend_LocalStorage_TagThree 中的_tags 数组。 This allows you to control how the object is serialized when JSON.stringify is called on it.例如:

this._tags.toJSON = function() 
    var values = [];

    for (var v in this) 
        if (this[v] instanceof Cache_Backend_LocalStorage_Tag) 
            values.push(this[v]);
        
    

    return JSON.stringify(values);
;

【讨论】:

感谢您的详尽回答。 @user634545 顺便说一句,您可能希望将其更改为使用数组。如果是这种情况,您仍然可以将其作为数组保存,只需确保将它们存储为数字索引(例如this._tags[0])以进行序列化而不是作为属性(例如this._tags["propertyName"])。 酷,我不知道 toJson。谢谢

以上是关于打字稿,序列化类对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中解码二进制数据字符串

将打字稿类转换为对象

打字稿->从Json.net转换字典的内容

用值实例化打字稿类实例(对象初始化)

Typescript:如何使用私有变量反序列化 JSON 对象?

打字稿可变泛型类,接受扩展公共基础的可变数量的类对象?