Javascript 取消按键拖动角度cdk拖放

Javascript 取消按键拖动角度cdk拖放,javascript,angular,angular-material,angular-cdk,Javascript,Angular,Angular Material,Angular Cdk,我在一个应用程序中工作,从角材料CDK实现新的拖放,我试图取消按Esc键的元素拖动事件,我的意思是,我开始拖动元素,但如果我在拖动元素时按Esc键,它应该回到我开始拖动它的位置,到目前为止,我还没有找到一种方法来做到这一点,有人知道我如何做到这一点吗。cdk文档中没有关于这一点的任何想法。我试着做这样的事情 模板 <div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)"> <div c

我在一个应用程序中工作,从角材料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>

但是到目前为止还没有成功。

您可以使用类似于

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

可以使用以下命令将拖动的项目移动到某个位置:

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};

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

@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
    if (event.key === 'Escape') {
        document.dispatchEvent(new Event('mouseup'));
    }
}
这是一个非常粗糙的解决方案,它有缺点。事实上,您并不是在取消拖动,而是在拖放。这意味着,如果您悬停在
cdkDropList
上或其中一个处于活动状态,它将触发该列表的
cdkdroplistdroped
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
    }
}

希望这能帮助你……:)

最好的方法是调用
event.source.\u dragRef.reset()ESC
键时编码>(注释中提到@AleRubis)。 现在的问题是,在cdkDrag事件(
ESC
key event)之外,从何处可以获得dragRef,当拖动开始时,可以将其保存在这样的组件变量中

组成部分:

cdkDragStarted=(事件)=>{
this.dragRef=event.source.\u dragRef;
}

模板:

拖拉段落


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

下面的示例中有两个部分。发生的情况是,结束事件只能在开始后收听,而该收听实例可以由按escape触发的主题停止

  • 在AfterViewInit中,从
    CdkDrag
    指令创建对已启动的事件发射器的订阅
  • 启动事件后,切换到侦听的流结束
  • 如果触发取消请求,则流将由
    takeUntil
    操作符结束,指令将调用
    reset()
    重置位置,并使用
    dispatchEvent()
    停止拖动过程
  • 否则,一旦触发end事件,就会从OP调用
    ondragend()
    方法
  • 除非有一些真正有趣的事情发生,否则end事件每次启动最多只会触发一次,因此不需要额外的
    take(1)

好的,我可以检查是否按下了键,但是我如何重置拖动到原始位置的元素并取消拖动。您可以在拖动开始事件时记住变量中的x和y位置,这不是特定的,问题是如何在拖动开始后取消拖动事件,并在按键时触发鼠标。在拖动带有任何事件的此类元素时,您可以获得其实际位置,并在取消时使用此位置。。如果您为问题创建stackbiz,这将非常有用。确定问题是如何取消拖动事件,而不是如何将拖动的元素返回到原始位置,仅取消拖动事件元素返回原始位置而不记住x或y位置,所以问题是如何取消元素的拖动,从拖动开始。你解决了吗?感谢,E.不幸的是,还没有…将拖动的元素重置为其原点,而不是手动设置元素转换和
源。_被动转换
现在可以执行
事件.source。_dragRef.reset()对我不起作用。reset()似乎什么也不做(使用Angular 9.1.X测试)。因此,我更喜欢@danizep的解决方案。
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
    }
}
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();
  }
}