angular - 使用 Angular 7 Material CDK 进行嵌套拖放

标签 angular drag-and-drop angular7 angular-cdk

我有一个拖放列表的嵌套树(不是树组件)。

当拖动另一个下拉列表中包含的下拉列表中的项目时 - 两个下拉列表都会触发 Enter/Exit 事件,这意味着当项目被删除时,它可以被放入内部下拉列表或容器中删除列表取决于其被删除的位置(注意:这些列表都是相互链接的)

我目前在想,如果拖动当前位于内部列表上方,最好的解决方案将是抑制容器列表触发的事件,但我不确定这是否是最佳解决方案或确切的做法此刻。

最佳答案

我确实设法找到了一个解决方案,尽管它绝对是 hacky 并且涉及使用 Angular 拖放 CDK 访问私有(private)值。

我使用 cdkDropListEnterPredicate 函数来检查它应该尝试放入哪个列表,我分配了 canDropPredicate 函数。

我还被迫通过以下方式访问指针位置:_pointerPositionAtLastDirectionChange,这不是很好,因为并非所有我希望看到传递到 cdkDropListEnterPredicate 的值都被传递。

canDropPredicate(): Function {
    const me = this;
    return (drag: CdkDrag<ResourceNode>, drop: CdkDropList<ResourceNode>): boolean => {
        const fromBounds = drag.dropContainer.element.nativeElement.getBoundingClientRect();
        const toBounds = drop.element.nativeElement.getBoundingClientRect();

        if (!me.intersect(fromBounds, toBounds)) {
            return true;
        }

        // This gross but allows us to access a private field for now.
        const pointerPosition: Point = drag['_dragRef']['_pointerPositionAtLastDirectionChange'];
        // They Intersect with each other so we need to do some calculations here.
        if (me.insideOf(fromBounds, toBounds)) {
          return !me.pointInsideOf(pointerPosition, fromBounds);
        }

        if (me.insideOf(toBounds, fromBounds) && me.pointInsideOf(pointerPosition, toBounds)) {
          return true;
        }
         return false;
    };
}

intersect(r1: DOMRect | ClientRect, r2: DOMRect | ClientRect): boolean {
    return !(r2.left > r1.right ||
        r2.right < r1.left ||
        r2.top > r1.bottom ||
        r2.bottom < r1.top);
}

insideOf(innerRect: DOMRect | ClientRect, outerRect: DOMRect | ClientRect): boolean {
    return innerRect.left >= outerRect.left &&
        innerRect.right <= outerRect.right &&
        innerRect.top >= outerRect.top &&
        innerRect.bottom <= outerRect.bottom &&
        !(
            innerRect.left === outerRect.left &&
            innerRect.right === outerRect.right &&
            innerRect.top === outerRect.top &&
            innerRect.bottom === outerRect.bottom
        );
}

pointInsideOf(position: Point, rect: DOMRect | ClientRect) {
  return position.x >= rect.left &&
        position.x <= rect.right &&
        position.y >= rect.top &&
        position.y <= rect.bottom;
}

关于angular - 使用 Angular 7 Material CDK 进行嵌套拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53271834/

相关文章:

javascript - 如何通过 react 拖放内容?

html - Angular 7 - 更改侧边栏和元素 z-index

angular - angular-cli工具的--base-href和--deploy-url参数有什么区别

c# - PictureBox 未落在正确的坐标上

java - JTree D&D DataFlavor 问题(在某些情况下为 NotSerializedException)

unit-testing - 错误 : Expected one matching request for criteria "Match by function: ", 未找到

css - 使用 Angular 7 中的最大化/最小化图标引导模式对话框调整大小

Angular 7禁用滚动到子路由更改顶部

angular - 尝试将 Stomp over SockJS 添加到 Angular 应用程序 : TS2307 Cannot find module

javascript - 在 Angular 中,如何确定事件路由?