如何使用 cdkDrag 获取 drop 后的位置?

Posted

技术标签:

【中文标题】如何使用 cdkDrag 获取 drop 后的位置?【英文标题】:How to get the position after drop with cdkDrag? 【发布时间】:2019-06-24 06:51:37 【问题描述】:

您好,我需要能够拖放一些 html 元素,但我需要知道拖放的结束位置。

使用cdkDrag 指令我从docs 看到有一个事件cdkDragEnded

这是我的模板:

<div cdkDrop>
  <div cdkDrag (cdkDragEnded)="dragEnd($event)">
    ...other stuff
  </div>
</div>

回调是:

dragEnd(event: CdkDragEnd) 
  console.log(event);

在控制台中我找到了我需要的东西,但它是事件 event.source._dragRef._passiveTransform 的私有属性,我在编译时收到错误消息。

你知道这些数据或我可以使用的其他东西是否以某种方式暴露了吗?

【问题讨论】:

【参考方案1】:

像这样在(getFreeDragPosition) 事件中使用source.getFreeDragPosition()

dragEnd($event: CdkDragEnd) 
    console.log($event.source.getFreeDragPosition());

【讨论】:

这应该是公认的答案。另请注意,您稍后可以使用 [cdkDragFreeDragPosition]="dragPosition" 恢复位置 简单的代码却用最正确的方式解决问题。 绝妙的答案!【参考方案2】:

我找到的解决方案是检索cdkDrag设置的style.transform

import  Component, ViewChild, ElementRef  from "@angular/core";
import  CdkDragEnd  from "@angular/cdk/drag-drop";

@Component(
  selector: "item",
  styles: [
    `
      .viewport 
        position: relative;
        background: #ccc;
        display: block;
        margin: auto;
      
      .item 
        position: absolute;
        background: #aaa;
      
    `
  ],
  template: `
    <div class="viewport" cdkDrop>
      <div
        #item
        class="item"
        cdkDrag
        (cdkDragEnded)="dragEnd($event)"
        [style.top.px]="initialPosition.y"
        [style.left.px]="initialPosition.x"
      >
        anything
      </div>
    </div>
  `
)
export class CanvasItemComponent 
  constructor() 

  @ViewChild("item")
  item: ElementRef;

  initialPosition =  x: 100, y: 100 ;
  position =  ...this.initialPosition ;
  offset =  x: 0, y: 0 ;

  dragEnd(event: CdkDragEnd) 
    const transform = this.item.nativeElement.style.transform;
    let regex = /translate3d\(\s?(?<x>[-]?\d*)px,\s?(?<y>[-]?\d*)px,\s?(?<z>[-]?\d*)px\)/;
    var values = regex.exec(transform);
    console.log(transform);
    this.offset =  x: parseInt(values[1]), y: parseInt(values[2]) ;

    this.position.x = this.initialPosition.x + this.offset.x;
    this.position.y = this.initialPosition.y + this.offset.y;

    console.log(this.position, this.initialPosition, this.offset);
  

或:

dragEnd(event: CdkDragEnd) 
    this.offset =  ...(<any>event.source._dragRef)._passiveTransform ;

    this.position.x = this.initialPosition.x + this.offset.x;
    this.position.y = this.initialPosition.y + this.offset.y;

    console.log(this.position, this.initialPosition, this.offset);
  

有没有更好的方法在不使用私有变量的情况下获取转换 x 和 y 值?

编辑: 该功能将添加到https://github.com/angular/material2/pull/14696

【讨论】:

嗨,我想弄清楚正在发生的事情。我可以看到有一个初始位置没有改变,但用于设置元素的位置。但是,在 dragend 位置正在计算,但它没有更新初始位置(用于幻灯片)。我尝试更新initialPosition,发现元素在跳来跳去,所以我不确定发生了什么。【参考方案3】:

我用来获取被拖动项目的位置在放置后的另一种解决方案是:

模板

<div
  cdkDrag
  (cdkDragEnded)="dragEnded($event)"
>
</div>

组件

  dragEnded($event: CdkDragEnd) 
    const  offsetLeft, offsetTop  = $event.source.element.nativeElement;
    const  x, y  = $event.distance;
    this.positionX = offsetLeft + x;
    this.positionY = offsetTop + y;
    this.showPopup = true;
    console.log( positionX, positionY );
  

设置位置

在某些情况下,您可能希望在拖动完成时显示一些内容。

<div
  *ngIf="showPopup"
  [ngStyle]="
    'left': positionX + 'px',
    'right': positionY + 'px'
  "
>
  I'm in position!
</div>

【讨论】:

我需要试试这个,我认为它与使用_passiveTransform 并没有太大区别,至少distance 本来是public 这之后你是怎么定位的?

以上是关于如何使用 cdkDrag 获取 drop 后的位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何将过滤后的计算属性与 ember-drag-drop 可排序对象一起使用?

jQuery如何获取transform缩放后的宽高坐标位置?

在 jquery drop UI 中,如何使用正确的鼠标位置将拖动元素克隆到放置位置?

drop table可以还原吗

恢复drop后的表空间

Oracle Drop表并未直接删除 drop table xx purge