Упакуйте и распакуйте сложную объектную архитектуру с помощью JSON - PullRequest
2 голосов
/ 10 марта 2012

Я заглянул в новое локальное хранилище HTML 5, и оно пока выглядит довольно круто.Я решил использовать JSON, чтобы сериализовать мои объекты в строки и проанализировать их обратно в объекты, что звучит очень хорошо.Однако легче сказать, чем сделать.Я обнаружил, что вы не можете просто JSON.stringify() объект и ожидать, что он будет хорошо упакован для вас, но я не могу понять, что я должен сделать вместо этого.

Это еще не все: мой объект содержит два массива, каждый из которых содержит объект другого типа и один из которых является многомерным.Вот как выглядит моя довольно сложная и взаимозависимая архитектура объектов:

function Vector2(x, y) {
    this.x = x;
    this.y = y;
}

function Bar(ID, position) {
    this.id = id;
    this.position = position;
}

function Goo(state, position) {
    this.on = state;
    this.position = position;
}

function Foo(name, size) {
    this.name = name;
    this.size = size;
    this.bars = new Array(width)
    this.goos = new Array(10);

    this.Initialize();
}

Foo.prototype.Initialize() {
    for(var x = 0;x<this.size.x;x++) {
            this.bars[x] = new Array(this.size.y);

        for(var y=0;y<this.size.y;y++) {
            this.bars[x][y] = new Bar(x + y, new Vector2(x, y));
        }
    }

    for(var i = 0;i<this.goos.length;i++) {
        this.goos[i] = new Goo(on, new Vector2(i, i/2 + 1));
    }
}

Каждый из этих объектов также имеет множество дополнительных функций, каждый из которых добавляется с использованием того же метода-прототипа, который я использовал для добавления метода вFoo.Как я уже сказал, сложный.У меня вопрос, как мне все это сериализовать?Мне действительно нужно прикрепить toJSON() функции к каждому объекту?

Наконец, как только я собрал все это и сохранил в localstorage, я знаю, как его получить, но я не знаю, как распаковать его с JSON.Это другой вопрос для другого времени, и я подозреваю, что было бы немного легче разобраться самому, когда я научусь собирать все вещи.

Примечание: я обычно не был бы таким потенциально широкимвопрос, но я не смог найти ничего здесь, на SO или с моим (по общему признанию, слабым) Google-фу, который действительно решает проблему, и я не знаю, как разбить этот вопрос дальше.

Ответы [ 4 ]

2 голосов
/ 10 марта 2012

Обычно вы не просто сериализуете сложные структуры данных в javascript, потому что обычная сериализация не обрабатывает разностные вещи, все имеют ссылки на один и тот же объект, не может обрабатывать циклические ссылки и т. Д. *

Вместо этого я бы порекомендовал вам выяснить, каково реальное состояние вашего приложения. Не вся объектная структура объекта, а минимальный объем информации, который фактически необходим для восстановления состояния ваших данных. Затем, как только вы это выясните (это должны быть только данные, а не реальные объекты), вы можете создать функции или методы для получения этих данных из ваших структур данных или создания новой структуры данных из данных.

При рассмотрении вашего кода фактическое состояние объекта Foo представляет собой двумерный массив объектов Bar и одномерный массив объектов Goo, а также name и size. A Bar просто имеет x, y и id. У Goo просто есть state, x и y. Было бы довольно легко написать метод Foo для генерации и метод Foo для принятия этого состояния из сохраненного хранилища.

1 голос
/ 10 марта 2012

Использование функций toJSON и fromJSON, вероятно, является правильным способом сделать это.Вам следует сохранять фактические уникальные данные только для любого данного объекта в формате JSON, поэтому было бы нецелесообразно сериализовать весь созданный экземпляр объекта по нескольким важным причинам, # 1 в том, что это просто не нужно.Также подумайте о случае, когда вы добавите или измените функции для одного из ваших объектов в ближайшем будущем: клиенты, которые сохранили свои собственные сериализованные объекты, никогда не получат ваши обновления.Простое хранение уникальных данных экземпляра и наличие функций для преобразования этих данных обратно в реальный объект (используя ваше самое последнее определение) - это путь.

0 голосов
/ 03 мая 2014

Надеюсь, я еще не опоздал, но я столкнулся с той же проблемой.

Я хотел сохранить объект обещания (возвращенный из вызова JQuery AJAX) в локальное хранилище.

К счастью, я наткнулся на небольшую библиотеку Javascript под названием Stash (http://rezitech.github.io/stash/).). Это делает возможным сериализацию сложных объектов Javascript в строки и разбор строки в объект Javascript.

Лучше всего, вам не нужно явно выполнять сериализацию / анализ, потому что типы данных автоматически распознаются и преобразуются, когда вы хотите сохранить / извлечь объект в / из локального хранилища.

Вот быстрый тест, который дал положительный результат

// the api endpoint

var url = "www.api-host.com/api/bla/blub";

// create json call returning promise object

var promise = $.getJSON(url);

// persist promise object in local storage using dash.js

var key = url;

stash.set(key, promise);

// retrieve promise object from local storage

var stashGet = stash.get(key);

// display in console

console.log(stashGet);

С уважением, Матиас

0 голосов
/ 10 марта 2012

Вы можете упаковать функции в строки:

var a = function() {return "a"};
a.toString()

// And also:

function b() {return "b"};
b.toString();

Таким образом, вы можете взломать JSON-источник (Дуглас Крокфорд) и включить поддержку функций. Или что-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...