Использование с Angular

Для интеграции Gridstack.js в проект на Angular необходимо сначала установить библиотеку через npm:

npm install gridstack
npm install @types/gridstack --save-dev

После установки подключение можно выполнить в модуле или компоненте. В Angular рекомендуется использовать динамическую инициализацию внутри ngAfterViewInit, чтобы гарантировать, что DOM-элементы уже созданы:

import { Component, AfterViewInit } from '@angular/core';
import { GridStack } from 'gridstack';
import 'gridstack/dist/h5/gridstack-dd-native';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements AfterViewInit {

  grid!: GridStack;

  ngAfterViewInit(): void {
    this.grid = GridStack.init({
      cellHeight: 80,
      float: true,
      animate: true
    }, '#grid-container');
  }
}

В HTML-шаблоне создаётся контейнер для грида:

<div id="grid-container" class="grid-stack">
  <div class="grid-stack-item" gs-w="3" gs-h="2">
    <div class="grid-stack-item-content">Элемент 1</div>
  </div>
  <div class="grid-stack-item" gs-w="2" gs-h="2">
    <div class="grid-stack-item-content">Элемент 2</div>
  </div>
</div>

Настройка параметров грида

Gridstack.js поддерживает множество опций, которые удобно настраивать через объект конфигурации при инициализации:

  • cellHeight — высота ячейки в пикселях или auto для адаптивной высоты.
  • float — разрешение плавающих элементов при перетаскивании.
  • animate — включение анимации при перемещении виджетов.
  • minRow и maxRow — ограничение количества рядов.
  • draggable и resizable — объекты с параметрами, управляемыми библиотекой interact.js.

Пример расширенной конфигурации:

this.grid = GridStack.init({
  column: 12,
  cellHeight: 100,
  float: false,
  animate: true,
  minRow: 3,
  maxRow: 6,
  draggable: {
    handle: '.grid-stack-item-content',
    scroll: true
  },
  resizable: {
    handles: 'se, sw'
  }
}, '#grid-container');

Добавление и удаление виджетов динамически

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

Добавление виджета:

addWidget(): void {
  this.grid.addWidget(
    `<div class="grid-stack-item" gs-w="3" gs-h="2">
      <div class="grid-stack-item-content">Новый элемент</div>
    </div>`
  );
}

Удаление виджета:

removeWidget(element: HTMLElement): void {
  this.grid.removeWidget(element);
}

Доступ к элементу можно получить через @ViewChild или через событие click.

Работа с событиями

Gridstack.js поддерживает множество событий для интеграции с Angular:

  • added — элемент добавлен
  • removed — элемент удалён
  • change — изменены размеры или позиция
  • dragstart / dragstop — начало и конец перетаскивания
  • resizestart / resizestop — начало и конец изменения размеров

Пример подписки на событие:

this.grid.on('change', (event, items) => {
  console.log('Изменения в сетке:', items);
});

События в Angular рекомендуется подписывать в ngAfterViewInit и отписывать при уничтожении компонента через ngOnDestroy.

Использование с реактивными формами

Gridstack можно интегрировать с Angular FormArray для динамического создания виджетов на основе данных:

import { FormBuilder, FormArray } from '@angular/forms';

constructor(private fb: FormBuilder) {}

dashboardForm = this.fb.group({
  widgets: this.fb.array([])
});

get widgets(): FormArray {
  return this.dashboardForm.get('widgets') as FormArray;
}

addWidgetToForm(widgetData: any): void {
  this.widgets.push(this.fb.control(widgetData));
  this.grid.addWidget(`<div class="grid-stack-item" gs-w="3" gs-h="2">
    <div class="grid-stack-item-content">${widgetData.title}</div>
  </div>`);
}

Такой подход позволяет хранить состояние грида в форме, что упрощает отправку данных на сервер или сохранение локально.

Адаптивность и отзывчивый дизайн

Gridstack.js позволяет задавать количество колонок для разных разрешений через опцию column с объектом медиазапросов:

this.grid = GridStack.init({
  column: 12,
  breakpoints: {
    lg: 1200,
    md: 992,
    sm: 768,
    xs: 480
  },
  columns: {
    lg: 12,
    md: 8,
    sm: 4,
    xs: 2
  }
}, '#grid-container');

В результате сетка будет автоматически перестраиваться под размеры экрана, сохраняя пропорции элементов и их позиции.

Стилизация и кастомизация элементов

Gridstack.js использует классы .grid-stack-item и .grid-stack-item-content. Для Angular компонентов удобно добавлять собственные CSS-классы:

.grid-stack-item-content {
  background-color: #3f51b5;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}

Для динамически создаваемых виджетов можно использовать Angular ngClass или ngStyle при генерации контента через шаблонные строки.

Совмещение с Angular CDK Drag & Drop

Хотя Gridstack имеет собственную поддержку перетаскивания через interact.js, возможна интеграция с Angular CDK Drag & Drop для унификации поведения перетаскивания в проекте. Для этого нужно отключить внутренний draggable Gridstack и использовать обработчики CDK:

<GridStack [draggable]="false">
  <div cdkDrag>Элемент</div>
</GridStack>

Затем синхронизировать позиции с помощью событий cdkDragEnded и методов Gridstack move.

Сохранение состояния грида

Gridstack предоставляет методы save() и load() для сохранения и восстановления расположения виджетов:

const serialized = this.grid.save();
localStorage.setItem('grid-layout', JSON.stringify(serialized));

// Восстановление
const layout = JSON.parse(localStorage.getItem('grid-layout')!);
this.grid.load(layout);

Такой подход позволяет реализовать персонализированные дашборды с сохранением позиций и размеров элементов между сессиями.


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