Работа с localStorage

Gridstack.js предоставляет мощные возможности для построения интерактивных сеточных интерфейсов с перетаскиваемыми и изменяемыми по размеру виджетами. Одним из ключевых аспектов практического применения является сохранение состояния сетки, чтобы при перезагрузке страницы пользователь видел тот же макет, который он создал. Для этого используется localStorage, встроенный механизм веб-хранилища браузера.


Получение состояния сетки

Каждый виджет в Gridstack имеет набор параметров, таких как x, y, width, height, id и пользовательские атрибуты. Для сохранения состояния необходимо собрать текущие позиции всех элементов сетки. Gridstack предоставляет метод save() через объект сетки (GridStack) для получения массива элементов:

const grid = GridStack.init();
function saveGrid() {
    const serializedData = grid.save(); // Получение текущего состояния
    localStorage.setItem('grid-layout', JSON.stringify(serializedData));
}

Ключевые моменты:

  • grid.save() возвращает массив объектов с координатами и размерами виджетов.
  • Перед сохранением в localStorage объект нужно сериализовать через JSON.stringify.

Восстановление состояния сетки

Для восстановления состояния используется метод load():

function loadGrid() {
    const savedData = localStorage.getItem('grid-layout');
    if (savedData) {
        const layout = JSON.parse(savedData);
        grid.removeAll(); // Очистка текущей сетки
        grid.load(layout); // Загрузка сохраненного состояния
    }
}

Особенности:

  • grid.removeAll() удаляет все существующие виджеты перед загрузкой сохраненной конфигурации.
  • grid.load(layout) автоматически размещает элементы согласно координатам x, y, width, height.

Автосохранение при изменениях

Gridstack позволяет подписываться на события, чтобы сохранять состояние при каждом изменении сетки:

grid.on('change', function(event, items) {
    saveGrid();
});

Рекомендации:

  • Событие change срабатывает при перемещении, изменении размера или удалении виджета.
  • Для уменьшения количества записей в localStorage можно использовать дебаунс.
let timeout;
grid.on('change', function(event, items) {
    clearTimeout(timeout);
    timeout = setTimeout(saveGrid, 200);
});

Добавление пользовательских данных виджетов

Gridstack позволяет хранить не только базовые координаты, но и любые пользовательские свойства, используя атрибуты data-* или свойства объекта виджета:

grid.addWidget({
    id: 'widget-1',
    x: 0,
    y: 0,
    width: 2,
    height: 2,
    content: '<div class="widget-content">Виджет 1</div>',
    customData: { color: 'red', text: 'Привет' }
});

При сохранении через grid.save(), по умолчанию сохраняются стандартные свойства. Чтобы включить дополнительные данные, необходимо расширить процесс сериализации:

function saveGridWithCustomData() {
    const serialized = grid.engine.nodes.map(node => ({
        x: node.x,
        y: node.y,
        width: node.w,
        height: node.h,
        id: node.id,
        customData: node.customData
    }));
    localStorage.setItem('grid-layout', JSON.stringify(serialized));
}

Очистка сохраненного состояния

Для сброса сетки к исходному виду или удаления данных из localStorage:

function resetGrid() {
    localStorage.removeItem('grid-layout');
    grid.removeAll();
}

Управление версиями макета

При обновлениях интерфейса может потребоваться обработка старых сохранений. Хорошей практикой является добавление версии к данным:

const layoutData = {
    version: 1,
    widgets: grid.save()
};
localStorage.setItem('grid-layout', JSON.stringify(layoutData));

При загрузке проверяется версия и выполняется миграция или очистка при несовпадении:

function loadGridWithVersion() {
    const saved = localStorage.getItem('grid-layout');
    if (saved) {
        const data = JSON.parse(saved);
        if (data.version === 1) {
            grid.removeAll();
            grid.load(data.widgets);
        } else {
            localStorage.removeItem('grid-layout'); // Очистка устаревшей версии
        }
    }
}

Работа с несколькими макетами

Для приложений с разными страницами или вкладками можно хранить несколько макетов, используя уникальные ключи в localStorage:

localStorage.setItem('dashboard-home', JSON.stringify(grid.save()));
localStorage.setItem('dashboard-analytics', JSON.stringify(grid.save()));

Загрузка осуществляется аналогично, через соответствующий ключ.


Итоговые рекомендации по localStorage и Gridstack

  • Сохранять только необходимые свойства виджетов (x, y, width, height, id) для уменьшения объема данных.
  • Использовать сериализацию JSON.stringify и десериализацию JSON.parse.
  • Подписываться на события change для автоматического обновления состояния.
  • Добавлять версии макета для управления совместимостью после обновлений интерфейса.
  • При работе с пользовательскими данными расширять объект виджета, но сериализовать их отдельно для корректного восстановления.

Эти техники обеспечивают полноценное сохранение и восстановление интерактивных сеток, делая интерфейс Gridstack.js гибким и надежным в долгосрочных проектах.