angular - CdkDrag 更新位置

标签 angular typescript drag-and-drop angular-material angular-cdk

我有多个 CdkDrag 元素,它们是从组件中的数组上的 ngFor 循环呈现的。当我删除一个元素时,我拼接数组。然后一些元素将更新那里的位置。我该如何避免呢?

我试图在删除其中一个之前获取所有可拖动元素的 freeDragPosition,然后重置它们的位置,但它没有用。

这是我的 app.component.html

<div class="container" id="container">
  <div *ngFor="let f of fields; let i = index;" 
    class="textField"
    [attr.data-guid]="f.guid"  
    (mouseenter)="onFieldHover($event)" 
    cdkDrag 
    cdkDragBoundary="#container"
    (cdkDragEnded)="onDragEnded($event)"
    [cdkDragFreeDragPosition]="f.position">
    <div class="textField-inner">
      <span style="color: hotpink; font-weight: bold">{{f.guid}}</span>
    </div>
    <div class="textField-options">
      <div class="textField-move" cdkDragHandle>
        <svg width="24px" fill="currentColor" viewBox="0 0 24 24">
          <path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path>
          <path d="M0 0h24v24H0z" fill="none"></path>
        </svg>
      </div>
      <div class="textField-remove">
        <i class="fas fa-trash-alt" (click)="onRemoveTextField(i)"></i>
      </div>
    </div>
  </div>
</div>
<button type="button" (click)="onTextFieldAdded()">Add a field</button>

这是我的 app.component.ts
import { Component } from '@angular/core';
import {CdkDrag, CdkDragEnd} from '@angular/cdk/drag-drop';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.scss' ]
})
export class AppComponent  {
  name = 'Angular';
  fields: Field[] = [];
    draggables: CdkDrag<any>[] = [];


  onDragEnded(event: CdkDragEnd){
        if(!this.draggables.find(f => f == event.source)){
            this.draggables.push(event.source);
        }
    }

  onFieldHover(event: any){
        if(event.target.classList.contains('initialPosition')){
            event.target.classList.remove('initialPosition');
            event.target.style.transform = "translate3d(250px, 180px, 0px)";
        }
    }

  onTextFieldAdded() {
        let field = new Field();
        field.index = this.fields.length;
        field.guid = this.newGuid();

        this.fields.push(field);
    }

  onRemoveTextField(index: number){
    let positions : any[] =[];

        this.draggables.forEach(drag => {
            let pos = { guid: drag.element.nativeElement.getAttribute("data-guid"), pos: drag.getFreeDragPosition()  };
            positions.push(pos);
            console.log(pos);
        });

        this.fields.splice(index, 1);

    positions.forEach(p => {
      let newPos = {x: p.pos.x, y: p.pos.y};
      console.log(newPos);
      this.fields.find(f => f.guid == p.guid).position = newPos;
        });
    }

  newGuid(): string{
     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        });
  }

}

export class Field{
    index: number;
    guid: string;
    position: {x: number, y: number}
}



当元素之一被删除时,我希望我的元素保持在当前位置。

这是一个代表问题的 .gif
element moving has i delete one

这是一个堆栈 Blitz
https://stackblitz.com/edit/angular-p3yfe7

最佳答案

在您的 stackblitz 中进行一些测试后,我能够重现您的预期行为,结果证明当 cdkDrag 在 ng 中时,它会绑定(bind)到同一个列表,当您从列表中删除一个 cdkDrag 时,它会呈现模板但具有新位置匹配 ngFor 列表顺序,以避免您可以覆盖 css 样式 position来自 cdkDrag。

在您的示例中,只需添加 position: absolute;.textField css 类。

关于angular - CdkDrag 更新位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58433814/

相关文章:

angular - 以 2/4 Angular 动态添加组件

java - Angular 6 : How to include html file into component?

javascript - Angular 2 中的自动滚动

typescript - 在 TypeScript 中,泛型参数位于函数之前

angular - 为什么我的 Angular 5 应用程序无法使用深层链接?

javascript - 如何建立像google+一样的拖放圈子系统

javascript - Angular 7 标题未设置

TypeScript:不能将 'new' 与类型缺少调用或构造签名的表达式一起使用

javascript - 拖放 - 如何在 dragstart 事件和 drop 事件中获取实际的 html

java - 通过 Eclipse 运行时拖放不起作用