0

我对 Angular 的 Drag'n'drop 有问题,确切地说是 DropZone。

TL;博士

Angular CDK Drag'n'Drop 中的 DropZone 仅适用于非滚动容器。如果它有滚动条,则必须使用 cdkScrollable,但这会使列向 4 个方向移动。这不包括它在粘性标题上的使用 - 尝试使用拖放操作以滚动到表格的最开头结束。

在此处输入图像描述

结构:

棕色容器有overflow-x 和overflow-y。高度设置为屏幕高度的 100%,其中宽度与内容匹配。

橙色的位置:相对。就这样。

蓝色容器包含带有表格标题的 div,位置为:sticky,并在滚动时悬停在表格上。我用它来模拟具有粘性行为的表格标题。由于对表格中任何位置(固定、粘性、绝对)的支持有限,我不得不这样做。

绿色是一个包含数据的表格。

问题:

我的任务是准备一个列与内容匹配的表格。需要能够使用拖放重新排列列。我努力的结果是上面的结构,它没有给人留下深刻的印象,但它确实有效。但是,有一个问题——如果屏幕很小并且列很多,则在抓取元素并将其移动到屏幕边缘后需要自动滚动。我用粉红色标记了浏览器中当前显示的内容。

在此处输入图像描述

解决方案原来是cdkScrollable,我用滚动条添加到主容器中,即棕色框架。不幸的是,有一个错误阻止我完成任务 - cdkScrollable 在 4 个方向上滚动。因此,如果我在表格的中间并且我决定更改列的顺序,cdkScrollable 会在屏幕顶部的滚动区域中捕捉到我,这使我回到表格的最开始。

在此处输入图像描述

我尝试了什么

  1. 带有中和 cdkScrollable 的 scrollTop 事件侦听器

它不起作用,因为 cdkScrollable 在 ngZone 中引入了 EventListener。结果,我们有两个监听器——一个加/减scrollTop,另一个将它返回到之前的状态。结果,整个表闪烁

  1. 拖动时关闭滚动

没用的。关闭溢出只会隐藏滚动,而不是滚动机制本身。滚动机制不能关闭,只能阻止特定的用户动作(例如触摸移动),但是当cdkScrollable有事件监听器时,该方法不起作用。

  1. CDK 拖放插入点

即使它在文档中(https://material.angular.io/cdk/drag-drop/overview#drag-preview-insertion-point)我也无法将它与代码连接起来。也没有使用示例。从 github 上的信息来看,有计划添加此选项,但最终放弃了,转而支持自定义类。

  1. 编写自己的滚动条

在此处输入图像描述

有效,但 DragZone 等于当前显示屏幕的宽度(紫色)。卷轴内的所有内容都被忽略;dragzone 不随屏幕移动。我怀疑放置是从 body 元素中计算的,所以不可能选择超过屏幕宽度。在下图中,1270 是鼠标相对于整个屏幕的当前位置。超出此区域的唯一方法是将鼠标放在浏览器之外。

在此处输入图像描述

  1. 重写 CDK Drag'n'drop 以获得所需的功能

我想过一个绑定到@Host 的指令,但CDK 代码是一场噩梦。在不知道依赖关系的情况下,我发现这是不可能的。

你知道如何解决它吗?

4

0 回答 0