【问题标题】:Cancel drag on key press Angular cdk Drag and Drop取消拖动按键 Angular cdk 拖放
【发布时间】:2019-05-05 15:47:16
【问题描述】:

我正在一个应用程序中实现从角度材料 CDK 进行新的拖放操作,并且我正在尝试取消按下 Esc 的元素的拖动事件,我的意思是,我开始拖动元素,但如果我按下Esc 当我拖动元素时,它应该回到我开始拖动它的位置,到目前为止我还没有找到这样做的方法,有谁知道我该怎么做。 cdk 文档中没有关于此的任何想法。我尝试做这样的事情。

模板

<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
  <div class="example-box" *ngFor="let movie of movies" (cdkDragEnded)="onDragEnded($event)" cdkDrag>{{movie}}</div>
</div>

Ts 组件

onDragEnded(event: CdkDragEnd) {
  console.log(event)
  event.source.element.nativeElement.style.transform = 'none';
  const source: any = event.source;
  source._passiveTransform = { x: 0, y: 0 };
}

但目前没有成功。

【问题讨论】:

  • 你解决了吗?谢谢,E。
  • 很遗憾还没有......
  • 要将拖动的元素重置为其原点,而不是手动设置元素变换和source._passiveTransform,您现在可以执行event.source._dragRef.reset();

标签: javascript angular angular-material angular-cdk


【解决方案1】:

你可以使用类似...

@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
    if (event.code === 'Escape') {
        // call dragend event
    }
}

【讨论】:

  • 好的,我可以检查是否按下了按键,但是如何将拖动的元素重置到原始位置并取消拖动。
  • 您可以在拖动开始事件时记住变量中的 x 和 y 位置
  • 这不是具体的,问题是如何在拖动开始后取消拖动事件并在按键时触发鼠标。
  • 在使用任何事件拖动此类元素时,您可以获得其实际位置并在取消时使用此位置。如果您创建问题的 stackbiz,它会很有帮助。
  • 好的问题是如何取消拖动事件而不是如何将被拖动的元素返回到原始位置,只取消拖动事件元素返回到原始位置而不记住x或y位置,所以问题是如何取消拖动开始的元素的拖动。
【解决方案2】:

您可以使用以下方式将拖动的项目移动到某个位置:

event['source']['element']['nativeElement']['style']['transform'] = 'translate3d(0,0,0)';
event['source']['_dragRef']['_activeTransform'] = {x: 0, y: 0};
event['source']['_dragRef']['_passiveTransform'] = {x: 0, y: 0};

【讨论】:

    【解决方案3】:

    我也长期面临这个问题。最后,我可以通过调度一个mouseup 事件来修复它,该事件将充当用户释放鼠标的角色。

    @HostListener('window:keyup', ['$event'])
    handleKeyboardEvent(event: KeyboardEvent) {
        if (event.key === 'Escape') {
            document.dispatchEvent(new Event('mouseup'));
        }
    }
    

    这是一个非常老套的解决方案,并带有它的缺点。实际上,您并没有取消拖动而是放下。这意味着如果您悬停cdkDropList 或其中一个处于活动状态,它将触发该列表的cdkDropListDropped emmiter。您可以通过添加标志轻松解决问题。

    private _canceledByEsq = false;
    
    @HostListener('window:keyup', ['$event'])
    handleKeyboardEvent(event: KeyboardEvent) {
        if (event.key === 'Escape') {
            this._canceledByEsq = true;
            document.dispatchEvent(new Event('mouseup'));
        }
    }
    
    handleDrop() {
        if (!this._canceledByEsq) {
            // Do my data manipulations
        }
    }
    

    希望这对您有所帮助... :)

    【讨论】:

      【解决方案4】:

      最好的方法是在ESC 按键上致电event.source._dragRef.reset();(正如评论中提到的@AleRubis)。 现在的问题是,您可以从哪里获得 cdkDrag 事件(ESC 键事件)之外的 _dragRef,您可以在拖动开始时将其保存在这样的组件变量中。

      组件:

      cdkDragStarted = (event) => { this.dragRef = event.source._dragRef; }

      模板:

      <p cdkDrag (cdkDragStarted)="cdkDragStarted($event)"> Draggable paragraph </p>

      【讨论】:

      • 对我不起作用。 dragRef.reset() 似乎什么都不做(用 Angular 9.1.X 测试)。因此,我更喜欢@danizep 的解决方案。
      【解决方案5】:

      这是一个使用 rxjs 的版本。它需要引用 CdkDrag 作为 ViewChild。不幸的是,由于没有公共方法可以停止在 DragRef 上拖动,因此您必须使用 dispatchEvent 作为结束拖动过程的唯一方法。

      下面的例子有两个部分。发生的情况是 ended 事件只能在开始后才能收听,并且该收听实例可以通过按退出触发的主题来停止。

      • 在 AfterViewInit 中,从 CdkDrag 指令创建对 started EventEmitter 的订阅。
      • 在开始事件之后,切换到收听的流结束
      • 如果取消请求被触发,流将由takeUntil 操作符结束,reset() 将在指令上调用以重置位置,dispatchEvent() 将用于停止拖动过程。
      • 否则一旦触发结束事件,就会从 OP 调用 onDragEnded() 方法。
      • 除非发生了一些真正有趣的事情,否则 ended 事件每次启动最多只会触发一次,因此不需要额外的take(1)
      private dragCancelRequest = new Subject();
      
      ngAfterViewInit() {
        this.drag.started.pipe(
          switchMap(({ source }) => source.ended.pipe(
            takeUntil(this.dragCancelRequest.pipe(tap(() => {
              source.reset();
              document.dispatchEvent(new Event('mouseup'));
            })))
          )),
          tap(x => this.onDragEnded(x))
        ).subscribe();
      }
      
      @HostListener('window:keyup', ['$event'])
      handleKeyboardEvent(event: KeyboardEvent) {
        if (event.key === 'Escape') {
          this.dragCancelRequest.next();
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-05
        • 2020-09-29
        相关资源
        最近更新 更多