import {OnDestroy, Input, OnInit, Directive, Output, EventEmitter, ElementRef} from '@angular/core'; import {DragulaService, dragula} from 'ng2-dragula'; import {Subscription} from 'rxjs'; import {DDSortDropResponse} from './dd-sort-drop-response.model'; /** * Директива сортировки Drag'n'Drop */ @Directive({ selector: '[gp-dd-sort]' }) export class DDSortDirective implements OnInit, OnDestroy { /** * Имя корзины в рамках которой происходит сортировка */ @Input('ddSortName') bagName: string; /** * CSS-класс который должен присутствовать в элементе на котором можно выполнять действие 'drag' * Если не указан - на всем элементе */ @Input('ddDragClass') dragClass: string; /** * Событие происходящее при действии 'drop'. Параметры в виде объекта, где: * bagName - Имя корзины * el - Элемент который был захвачен * target - Элемент в который был перемещен захваченый элемент * source - Элемент из которого был перемещен захваченый элемент * sibling - Элемент перед которым был помещен захваченый элемент (null - если в конец списка) * @type {EventEmitter} */ @Output() ddDrop: EventEmitter = new EventEmitter(); private bag: any; private drake: any; private container: any; /** * Подписки на события dragulaService-а * @type {Array} */ private subscriptions: Subscription[] = []; constructor(private dragulaService: DragulaService, private el: ElementRef) { this.container = el.nativeElement; } /** * Инициализация компонента */ ngOnInit(): void { this.bag = this.dragulaService.find(this.bagName); if (this.bag) { this.drake = this.bag.drake; this.drake.containers.push(this.container); } else { this.drake = dragula([this.container], { revertOnSpill: true, moves: (el: any, source: any, handle: any) => { return (this.dragClass) ? handle.classList.contains(this.dragClass) : true; } }); this.dragulaService.add(this.bagName, this.drake); } this.subscriptions.push( this.dragulaService.drop.subscribe((value: any[]) => { value = value || []; const bagName = value[0] || ''; if (bagName === this.bagName) { this.ddDrop.emit( { bagName: bagName, el: value[1] || null, target: value[2] || null, source: value[3] || null, sibling: value[4] || null }); } }) ); } /** * Уничтожение компонента */ ngOnDestroy(): void { this.subscriptions.forEach((sub: Subscription) => { sub.unsubscribe(); }); this.dragulaService.destroy(this.bagName); } }