Ale*_*rdy 4 drag-and-drop autoscroll scrollable angular angular-cdk
因此,我正在沙箱中工作,以模仿我希望实现此拖放操作的应用程序的环境。很抱歉这么啰嗦,但我真的想确保正确解释问题,因为我已经看到了几篇关于此的旧帖子未回答或回答错误问题的问题。
简洁版本
诀窍是,cdk 拖放自动滚动功能似乎只能在与整个窗口大小相关的情况下开箱即用,或者如果它是带有溢出-y 的固定高度 div:滚动(这就是我正在尝试的)做),那么这需要在 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>
Run Code Online (Sandbox Code Playgroud)
这是带有 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>
Run Code Online (Sandbox Code Playgroud)
此时,我可以在窗口中拖动,但自动滚动不起作用,因此我将自动滚动添加到父组件的 Type Script 文件中,更改 (mousemove) 上的滚动位置。对于开始向上/向下滚动的位置,这些值是基于我正在使用的页面上的硬编码。
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
子组件 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);
}
}
Run Code Online (Sandbox Code Playgroud)
(可能有一些我不使用一些失败尝试留下的东西)
无论如何:我知道这很长,但我试图克服/弄清楚的主要行为是,当我拖动一个项目并滚动远离其初始视图端口中的一小部分数组时,cdk 拖放不再让我将项目放入数组的该位置...该项目仍然显示为“拖动”,但这让我相信它不再识别“拖放区域”
小智 9
我认为解决方案可能是将cdkScrollable指令放入一个容器中,该容器内有 CDK 拖放组件。
| 归档时间: |
|
| 查看次数: |
7972 次 |
| 最近记录: |