Для интеграции Dragula в Angular используется официальная обёртка
ng2-dragula, которая обеспечивает удобный доступ к
функционалу Dragula через Angular-сервисы и директивы. Установка
производится через npm:
npm install dragula ng2-dragula --save
Импорт модуля в корневой модуль приложения:
import { DragulaModule } from 'ng2-dragula';
@NgModule({
imports: [
DragulaModule.forRoot()
]
})
export class AppModule { }
После этого Dragula готов к использованию в компонентах.
Dragula оперирует контейнерами, между которыми осуществляется
перетаскивание элементов. В Angular создаются обычные HTML-элементы с
директивой dragula:
<div class="container" [dragula]="'TASKS'">
<div *ngFor="let task of tasks">{{ task.name }}</div>
</div>
<div class="container" [dragula]="'TASKS'">
<div *ngFor="let task of completedTasks">{{ task.name }}</div>
</div>
Ключевой момент: идентификатор 'TASKS' связывает
контейнеры, позволяя перемещать элементы между ними. Можно создавать
несколько групп с разными идентификаторами для разделения зон
перетаскивания.
Dragula поддерживает множество опций, которые задаются через сервис
DragulaService. Это позволяет гибко управлять поведением
перетаскивания. Пример конфигурации:
import { DragulaService } from 'ng2-dragula';
@Component({...})
export class TasksComponent {
constructor(private dragulaService: DragulaService) {
this.dragulaService.createGroup('TASKS', {
moves: (el, source, handle, sibling) => handle.classList.contains('handle'),
copy: false,
revertOnSpill: true,
direction: 'vertical'
});
}
ngOnDestroy() {
this.dragulaService.destroy('TASKS');
}
}
Ключевые параметры:
moves: определяет, какой элемент может быть захвачен
для перетаскивания.copy: разрешает или запрещает копирование элементов
вместо перемещения.revertOnSpill: возвращает элемент на исходное место при
ошибочном переносе.direction: задаёт направление перетаскивания
('vertical' или 'horizontal').Dragula предоставляет набор событий, которые позволяют отслеживать состояние перетаскивания и изменять данные Angular. Основные события:
drag: элемент начал перетаскиваться.drop: элемент был перемещён в новый контейнер.over: элемент над контейнером.out: элемент покинул контейнер.remove: элемент удалён через бросок за пределы
контейнера.shadow: создаётся тень элемента при перемещении.Пример подписки на события:
this.dragulaService.dropModel('TASKS').subscribe(({ source, target, item, sourceModel, targetModel, index }) => {
console.log('Элемент перемещён:', item);
console.log('Новая позиция в модели:', index);
});
Использование dropModel и других *Model
событий позволяет автоматически синхронизировать данные в Angular с
визуальным состоянием.
Dragula позволяет создавать и удалять группы динамически. Это полезно для компонентов с изменяющейся структурой контейнеров:
addGroup(name: string) {
this.dragulaService.createGroup(name, {
revertOnSpill: true
});
}
removeGroup(name: string) {
this.dragulaService.destroy(name);
}
Динамическое управление группами особенно важно в больших приложениях с множеством зон перетаскивания.
Dragula работает не только с DOM, но и с массивами Angular. Для этого
используется привязка через *ngFor и события
dropModel/removeModel. Это гарантирует, что
любые перемещения элементов будут автоматически отражены в данных:
<div [dragula]="'TASKS'" [dragulaModel]="tasks">
<div *ngFor="let task of tasks">{{ task.name }}</div>
</div>
Перемещение элемента автоматически обновляет массив
tasks. Таким образом, визуальные изменения и состояние
модели остаются синхронизированными без дополнительного кода.
moves и accepts позволяют запрещать
перемещение определённых элементов или их попадание в конкретные
контейнеры..gu-mirror, .gu-transit и
.gu-hide для плавных анимаций.BehaviorSubject или Observable для
динамического обновления списков.dropModel обеспечивают
перемещение элементов между компонентами без потери данных.Dragula добавляет классы для управления состоянием перетаскивания:
.gu-mirror — копия элемента, которая перемещается по
экрану..gu-transit — элемент в процессе перетаскивания..gu-hide — скрывает оригинальный элемент при
перетаскивании..gu-unselectable — предотвращает выделение текста при
захвате элемента.Использование этих классов в сочетании с CSS-переходами и анимациями позволяет создавать визуально привлекательные интерфейсы перетаскивания.
Dragula можно использовать внутри Angular-форм. События
dropModel можно подключать к реактивным формам, обновляя
FormArray при перемещении элементов:
this.dragulaService.dropModel('TASKS').subscribe(({ sourceModel, targetModel }) => {
this.form.setControl('tasks', new FormArray(targetModel.map(task => new FormControl(task))));
});
Это обеспечивает полную совместимость с механизмами валидации и сохранения состояния формы, не нарушая принципов реактивного программирования Angular.