如何更改 Angular Material CdkDroplist 行为以模拟“自由"放置区? [英] How to change an Angular Material CdkDroplist behavior to emulate a “free” dropzone?

查看:26
本文介绍了如何更改 Angular Material CdkDroplist 行为以模拟“自由"放置区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的目标是制作一个全宽的 dropzone.我可以在其中删除小部件"并在放置区周围自由拖动它们.但不同的是,我也可以删除列表小部件,在其中我也可以删除其他小部件..

所以我有这个 stackblitz使用代码,以及此视频显示奇怪的行为

有什么帮助吗?我可以删除 cdkdroplist 指令并将所有内容假定为可拖动项,但会丢失元素上的列表功能...

同样的问题家伙

app.component.html

<div class="example-box widget item{{item.id}}";id="item{{item.id}}";*ngFor=让待办事项的项目";cdk拖拽(cdkDragReleased)=cdkDragReleased($event, item)";[cdkDragData]=项目"[ngStyle]="{'transform': 'translate3d('+ item.dragPosition.x +'px,'+ item.dragPosition.y +'px,'+ item.dragPosition.z +'px)'}>{{item.label}}</div>

<div class="example-container widget widget-a"><h2>进行中</h2>

<div class="example-box item{{item.id}}";id="item{{item.id}}";*ngFor=让正在进行的项目";cdk拖拽(cdkDragReleased)=cdkDragReleased($event, item)";[cdkDragData]=item">{{item.label}}

<div class="example-container widget widget-b"><h2>完成</h2>

<div class="example-box item{{item.id}}";id="item{{item.id}}";*ngFor=让完成的项目";cdk拖拽(cdkDragReleased)=cdkDragReleased($event, item)";[cdkDragData]=item">{{item.label}}

app.component.ts

导出类 AppComponent {widgetIds = ['todo', 'inprogress', 'done'];待办事项 = [{ id: 1, label: 'Item 1', dragPosition: { x: 45, y: 549, z: 0 } },{ id: 2, label: 'Item 2', dragPosition: { x: 190, y: 236, z: 0 } },{ id: 5, label: 'Item 5', dragPosition: { x: 93, y: 142, z: 0 } }];进行中 = [{ id: 3, label: 'Item 3', dragPosition: { x: 0, y: 0, z: 0 } },{ id: 6, label: 'Item 6', dragPosition: { x: 0, y: 0, z: 0 } },{ id: 7, label: 'Item 7', dragPosition: { x: 0, y: 0, z: 0 } }];完成 = [{ id: 4, label: 'Item 4', dragPosition: { x: 0, y: 0, z: 0 } },{ id: 8, label: 'Item 8', dragPosition: { x: 0, y: 0, z: 0 } }];构造函数(){}drop(事件:CdkDragDrop){if (event.previousContainer === event.container) {moveItemInArray(event.container.data,event.previousIndex,事件.currentIndex);} 别的 {传输数组项(event.previousContainer.data,event.container.data,event.previousIndex,事件.currentIndex);}}cdkDragReleased(事件:CdkDragRelease<任何>,项目){const widDomElement: any = document.querySelector(`.item${item.id}`);const el: any = document.querySelector(`.cdk-drag-preview.item${item.id}`);让 arrT = el.style.transform.replaceAll('px', '').全部替换(' ', '').全部替换(')', '').replaceAll('translate3d(', '').分裂(',');item.dragPosition = {x: 数字(arrT[0]),y:数字(arrT[1]),z:数字(arrT[2])};}}

解决方案

这是 Material CDK 中的一个问题.团队解决了这个问题:

https://github.com/angular/components/commit/7508f46e7d1fd2eb0c20fdf8b913aacfcad5ea5a"

https://github.com/angular/components/issues/22407

The goal is to make a full-width dropzone. In which I can drop "widgets" and drag them freely around the dropzone. But the twist is that I can also drop list widgets, in which I can drop other widgets as well..

So I have this stackblitz With the code, and this video showing the strange behavior

Any help? I could remove the cdkdroplist directive and assume everything as a Draggable item but will lost the list features on the elements...

Same problem as this guy

app.component.html

<div
  cdkDropList
  id="todo"
  [cdkDropListData]="todo"
  [cdkDropListConnectedTo]="widgetIds"
  class="example-list board"
  (cdkDropListDropped)="drop($event)">

    <div class="example-box widget item{{item.id}}"
      id="item{{item.id}}" 
      *ngFor="let item of todo" 
      cdkDrag
      (cdkDragReleased)="cdkDragReleased($event, item)"
      [cdkDragData]="item"
      [ngStyle]="{
                'transform': 'translate3d('+ item.dragPosition.x +'px,'+ item.dragPosition.y +'px,'+ item.dragPosition.z +'px)'
            }">{{item.label}}</div>
</div>

<div class="example-container widget widget-a">
  <h2>In Progress</h2>

  <div
    cdkDropList
    id="inprogress"
    [cdkDropListData]="inprogress"
    [cdkDropListConnectedTo]="widgetIds"
    class="example-list"
    (cdkDropListDropped)="drop($event)">
    <div class="example-box item{{item.id}}"
      id="item{{item.id}}" 
      *ngFor="let item of inprogress" 
      cdkDrag
      (cdkDragReleased)="cdkDragReleased($event, item)"
      [cdkDragData]="item">{{item.label}}</div>
  </div>
</div>

<div class="example-container widget widget-b">
  <h2>Done</h2>

  <div
    cdkDropList
    id="done"
    [cdkDropListData]="done"
    [cdkDropListConnectedTo]="widgetIds"
    class="example-list"
    (cdkDropListDropped)="drop($event)">
    <div class="example-box item{{item.id}}"
      id="item{{item.id}}" 
      *ngFor="let item of done" 
      cdkDrag
      (cdkDragReleased)="cdkDragReleased($event, item)"
      [cdkDragData]="item">{{item.label}}</div>
  </div>
</div>

app.component.ts

export class AppComponent {
  widgetIds = ['todo', 'inprogress', 'done'];

  todo = [
    { id: 1, label: 'Item 1', dragPosition: { x: 45, y: 549, z: 0 } },
    { id: 2, label: 'Item 2', dragPosition: { x: 190, y: 236, z: 0 } },
    { id: 5, label: 'Item 5', dragPosition: { x: 93, y: 142, z: 0 } }
  ];

  inprogress = [
    { id: 3, label: 'Item 3', dragPosition: { x: 0, y: 0, z: 0 } },
    { id: 6, label: 'Item 6', dragPosition: { x: 0, y: 0, z: 0 } },
    { id: 7, label: 'Item 7', dragPosition: { x: 0, y: 0, z: 0 } }
  ];

  done = [
    { id: 4, label: 'Item 4', dragPosition: { x: 0, y: 0, z: 0 } },
    { id: 8, label: 'Item 8', dragPosition: { x: 0, y: 0, z: 0 } }
  ];

  constructor() {}

  drop(event: CdkDragDrop<any>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
  }

  cdkDragReleased(event: CdkDragRelease<any>, item) {
    const widDomElement: any = document.querySelector(`.item${item.id}`);
    const el: any = document.querySelector(`.cdk-drag-preview.item${item.id}`);
    let arrT = el.style.transform
      .replaceAll('px', '')
      .replaceAll(' ', '')
      .replaceAll(')', '')
      .replaceAll('translate3d(', '')
      .split(',');

    item.dragPosition = {
      x: Number(arrT[0]),
      y: Number(arrT[1]),
      z: Number(arrT[2])
    };
  }
}

解决方案

This was a problem within the Material CDK. The team solved this issue:

https://github.com/angular/components/commit/7508f46e7d1fd2eb0c20fdf8b913aacfcad5ea5a

https://github.com/angular/components/issues/22407

这篇关于如何更改 Angular Material CdkDroplist 行为以模拟“自由"放置区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆