【问题标题】:How to get the position after drop with cdkDrag?如何使用 cdkDrag 获取 drop 后的位置?
【发布时间】: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 的私有属性,我在编译时收到错误消息。

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

【问题讨论】:

    标签: angular drag-and-drop draggable


    【解决方案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
    • 这之后你是怎么定位的?
    猜你喜欢
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多