2015-03-23 7 views
6

Как сериализовать эти классы в JSON?Typcript, сериализуйте объекты класса

Как видно из приведенного ниже примера, JSON.stringify() не сериализует список Cache_Backend_LocalStorage_Tag внутри объекта Cache_Backend_LocalStorage_TagThree.

Что мне не хватает?

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); 

ответ

4

Причина

Это потому, что вы присваиваете свойства массива и массив свойств, не будут включены в 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[] = []) { 

To:

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

Просто для удовольствия - Изменение поведения сериализации по умолчанию (не рекомендуется)

Если вы действительно хотите, чтобы сделать эту работу с массивом с вашей текущей настройкой (я не уверен, почему), вы можете переопределить, как выполняется сериализация. Для этого добавьте метод toJSON в массив _tags в Cache_Backend_LocalStorage_TagThree. 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); 
}; 
+0

Благодарим за подробный ответ. – user634545

+0

@ user634545, кстати, вы можете изменить его, чтобы вместо этого использовать массив. Если это так, вы все равно можете использовать его как массив, просто убедитесь, что вы храните их с помощью числового индекса (например, 'this._tags [0]') для сериализации вместо свойства (например, 'this._tags [ "PropertyName"] '). –

+0

Прохладный, я не знал о Йонсе. благодаря – user634545

Смежные вопросы