Итак, я работаю в «песочнице», чтобы имитировать среду приложения. Я буду sh реализовывать это перетаскивание. Извините, что так многословно, но я действительно хочу убедиться, что я объясню проблема правильно, поскольку я видел несколько более старых сообщений по этому вопросу, которые либо не получили ответа, либо ответили на неправильный вопрос.
КРАТКАЯ ВЕРСИЯ
- cdk dnd не будет автоматически прокручиваться
- сделал свой собственный автопрокрутку
- cdk dnd не выпадет после прокрутки
Хитрость заключается в том, что кажется, что функция автоматической прокрутки cdk Drag and Drop работает только из коробки по отношению либо ко всему размеру окна, либо, если это div с фиксированной высотой с overflow-y: scroll (именно это я и пытаюсь сделать), то это должно быть на уровне cdkDropList. К сожалению, из-за компонентной архитектуры моего приложения, это НЕ в настоящее время вариант.
Я написал свою собственную функцию автопрокрутки , которая прокручивает div в зависимости от положения экрана мыши во время перетаскивания элемента, я понял, что это работает, но большая проблема в том, что как только div начинает прокручивать, вы теряете возможность удалить элемент в списке.
Вот HTML для моего родительского компонента (div с фиксированной высотой и положением переполнения)
<div #ScrollDiv style="height: 200px; width: 200px; overflow-y: scroll; padding: 5px;">
<app-child (itemSelected)="itemSelection($event)"></app-child>
</div>
Вот шаблон дочернего компонента с директивами cdk
<div cdkDropList style="border: 2px solid purple;" (cdkDropListDropped)="drop($event)">
<div cdkDrag [cdkDragData]="draggers" *ngFor="let item of draggers; let i = index"
style="height: 30px; border: 2px solid blue; margin: 5px"
(mousedown)="grabDrag()">
{{item}}</div>
</div>
На данный момент я могу перетащить в свое окно, но автопрокрутка не работает, поэтому я добавил авто выделите файл сценария типа родительского компонента, изменив положение прокрутки (перемещение мыши). Для позиций, с которых начинается прокрутка вверх / вниз, значения являются жестко закодированными базами на странице, с которой я работаю.
import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, ChangeDetectionStrategy } from '@angular/core';
import { Subscription, fromEvent } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
title = 'drag-sizing';
itemSelected = false;
isScrolling = false;
smoothScroll;
scrollSpeed = 2;
@ViewChild('ScrollDiv', {static: true}) public myScrollContainer: ElementRef;
ngAfterViewInit() {
fromEvent(this.myScrollContainer.nativeElement, 'mousemove').subscribe((event: MouseEvent) => {
if (this.itemSelected) {
if (event.clientY < 150) {
this.isScrolling = true;
if (!this.smoothScroll) {
this.smoothScroll = setInterval(() => {
this.scrollUp();
}, 10);
}
} else if (event.clientY > 300) {
this.isScrolling = true;
if (!this.smoothScroll) {
this.smoothScroll = setInterval(() => {
this.scrollDown();
}, 10);
}
} else {
clearInterval(this.smoothScroll);
this.smoothScroll = undefined;
this.isScrolling = false;
}
} else {
clearInterval(this.smoothScroll);
this.smoothScroll = undefined;
this.isScrolling = false;
}
});
}
scrollInner() {
this.myScrollContainer.nativeElement.scrollTop += 2;
}
itemSelection(event) {
this.itemSelected = event;
if (!this.itemSelected) {
clearInterval(this.smoothScroll);
this.smoothScroll = undefined;
}
}
scrollUp() {
if (this.isScrolling === true) {
this.myScrollContainer.nativeElement.scrollTop -= this.scrollSpeed;
}
}
scrollDown() {
if (this.isScrolling === true) {
this.myScrollContainer.nativeElement.scrollTop += this.scrollSpeed;
}
}
}
и дочерний компонент TypeScript, который выдает, что элемент перетаскивается и имеет функцию перетаскивания.
import { Component, OnInit, Input, ElementRef, ViewChild, AfterViewInit, Output, EventEmitter } from '@angular/core';
import { Subscription, fromEvent, BehaviorSubject, Subject } from 'rxjs';
import { CdkDragDrop, transferArrayItem, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements AfterViewInit {
@Output() itemSelected = new EventEmitter<boolean>();
itemIsSelected = false;
draggers = ['item 0', 'item 1', 'item 2'...]
ngAfterViewInit(): void {
fromEvent(document, 'mouseup').subscribe(() => {
this.itemIsSelected = false;
this.itemSelected.emit(this.itemIsSelected);
});
}
grabDrag() {
this.itemIsSelected = true;
this.itemSelected.emit(this.itemIsSelected);
}
drop(event: CdkDragDrop<any>) {
console.log(event);
moveItemInArray(this.draggers, event.previousIndex, event.currentIndex);
}
}
( могут быть некоторые вещи, которые я не использую, оставшиеся после некоторых неудачных попыток )
ВСЕГДА: я знаю, что это было долго, но Основное поведение, которое я пытаюсь преодолеть / выяснить, это Когда я перетаскиваю элемент и прокручиваю его от маленького куска массива в его начальном порту просмотра, перетаскивание cdk больше не позволяет мне бросать элемент в это положение массива ... элемент по-прежнему выглядит как DRAGGING, но это наводит меня на мысль, что он больше не распознает DROP ZONE
![Heres What it looks like](https://i.stack.imgur.com/pRRmw.png)