Обертки и адаптеры

Gridstack.js — это библиотека для динамической сеточной верстки с поддержкой drag-and-drop и ресайза элементов. Важной частью расширяемости и интеграции Gridstack.js являются обертки (wrappers) и адаптеры (adapters). Они позволяют подключать Gridstack.js к различным фреймворкам и библиотекам, сохраняя при этом стандартный API и обеспечивая совместимость с существующим кодом.

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


Обертки для фреймворков

Gridstack.js поставляется с базовой Vanilla JS реализацией, но для React, Angular и Vue существуют специальные обертки. Они реализуют следующие ключевые задачи:

  1. Синхронизация состояния сетки

    • Обертки следят за изменениями в props (React, Vue) или Input/Output (Angular) и обновляют Gridstack-сетку.
    • Обеспечивается двусторонняя связь между моделью данных и визуальным состоянием сетки.
  2. Жизненный цикл компонентов

    • В React обертка Gridstack.jsx инициирует сетку в componentDidMount и уничтожает её в componentWillUnmount.
    • В Angular адаптер интегрирован через директивы, которые создают сетку при инициализации компонента и удаляют при разрушении.
  3. Управление событиями

    • Drag-and-drop и resize события пробрасываются через пропсы или Output события фреймворка.
    • Обертка позволяет подписываться на события change, added, removed, resized, не используя прямой доступ к DOM.

Пример для React (синтаксис JSX):

import { GridStack } from 'gridstack';
import 'gridstack/dist/h5/gridstack-dd-native';

function MyGrid({ layout, onChange }) {
  const gridRef = React.useRef();

  React.useEffect(() => {
    const grid = GridStack.init({ staticGrid: false }, gridRef.current);
    grid.load(layout);
    grid.on('change', (event, items) => onChange(items));
    return () => grid.destroy();
  }, [layout]);

  return <div ref={gridRef} className="grid-stack"></div>;
}

Адаптеры событий

Gridstack.js использует собственные внутренние события для управления изменениями элементов. Адаптер событий позволяет связывать эти события с внешними библиотеками или пользовательским кодом без изменения ядра Gridstack.js.

  • Пример адаптера для сторонней drag-and-drop библиотеки:

    • Создается объект адаптера, реализующий методы onDragStart, onDrag, onDragStop.
    • Адаптер подключается к внутренним hook’ам Gridstack.js, которые вызываются при начале и завершении перетаскивания элементов.
    • Это позволяет использовать кастомные анимации, ограничения по сетке и интеграцию с внешним хранилищем состояния.

Обертки для визуальных компонентов

Gridstack.js не ограничивается только сеткой элементов. Часто требуется интеграция с визуальными компонентами:

  1. Виджеты и панели

    • Каждый элемент сетки (grid-item) можно обернуть в компонент, который содержит собственное содержимое и управление.
    • Обертка обеспечивает, чтобы внутренние события виджета не конфликтовали с drag-and-drop Gridstack.js.
  2. Реактивные обновления

    • Для Vue или React обертка позволяет менять содержимое виджета динамически, не пересоздавая весь DOM сетки.
    • Используется метод grid.update() для обновления размеров и позиции элементов при изменении состояния.

Создание кастомных оберток

Кастомные обертки полезны, когда требуется нестандартное поведение:

  1. Шаг 1 — Инициализация Gridstack

    • Создается экземпляр Gridstack с базовыми настройками (cellHeight, verticalMargin, disableResize, float).
  2. Шаг 2 — Определение API обертки

    • Методы addWidget, removeWidget, updateWidget, saveLayout инкапсулируют работу с DOM.
    • События Gridstack.js пробрасываются через методы обертки.
  3. Шаг 3 — Подключение адаптера

    • Адаптер связывает события внешней логики (например, drag-and-drop библиотеки или реактивного хранилища) с методами обертки.
    • Позволяет сохранять единую точку управления сеткой без прямого обращения к элементам DOM.

Пример базового адаптера:

class DragAdapter {
  constructor(grid) {
    this.grid = grid;
  }
  
  onDragStart(event, el) {
    console.log('Начало перетаскивания', el);
  }

  onDragStop(event, el) {
    console.log('Конец перетаскивания', el);
    this.grid.save(); // сохраняем текущее состояние
  }
}

Рекомендации по использованию

  • Для сложных приложений использовать официальные обертки под выбранный фреймворк.
  • Для интеграции с нестандартными drag-and-drop решениями создавать собственные адаптеры событий.
  • Все манипуляции с DOM должны проходить через обертку или API Gridstack.js, чтобы не нарушить внутреннюю логику сетки.
  • Использовать адаптеры для сохранения состояния сетки в локальном хранилище, Redux или Vuex.

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