[英]Drag and drop cdk Angular material
我創建了 1 個帶有圖像的容器(使用 ngb-carousel)和 3 個放置這些圖像的放置區,但是當我嘗試在它們之間傳輸項目時遇到了一些問題。 首先,每當我嘗試將項目從我的圖像容器移動到任何放置區域時,我總是得到相同的索引。
這是我的模板
<mat-card class="card">
<div
cdkDropList
#todoList="cdkDropList"
[cdkDropListData]="images"
[cdkDropListConnectedTo]="[doneList, intermedio, menos]"
cdkDropListOrientation="horizontal"
class="contenedor">
<ngb-carousel *ngIf="images">
<ng-template *ngFor="let img of images" ngbSlide>
<div class="picsum-img-wrapper" [cdkDragData]="img" cdkDrag>
<img [src]="path+img.imagen" width="100%" alt="Random first slide">
</div>
</ng-template>
</ngb-carousel>
</div>
<div class="results">
<div class="talents">
<div class="example-container">
<h4>(+) Talento más desarrollado</h4>
<div cdkDropList #doneList="cdkDropList" [cdkDropListData]="list2"
[cdkDropListConnectedTo]="[intermedio, menos]"
class="example-list" (cdkDropListDropped)="drop($event)">
<ol class="example-box">
<li *ngFor="let l2 of list2" [cdkDragData]="l2" cdkDrag>
{{l2.nombre}}
</li>
</ol>
</div>
</div>
</div>
<div class="talents">
<div class="example-container">
<h4>Talento Intermedio</h4>
<div cdkDropList #intermedio="cdkDropList" [cdkDropListData]="list3"
[cdkDropListConnectedTo]="[doneList, menos]"
class="example-list" (cdkDropListDropped)="drop($event)">
<ol class="example-box">
<li *ngFor="let l3 of list3" [cdkDragData]="l3" cdkDrag>
{{l3.nombre}}
</li>
</ol>
</div>
</div>
</div>
<div class="talents">
<div class="example-container">
<h4>(-) Talento menos desarrollado</h4>
<div cdkDropList #menos="cdkDropList" [cdkDropListData]="list4"
[cdkDropListConnectedTo]="[intermedio, doneList]"
class="example-list" (cdkDropListDropped)="drop($event)">
<ol class="example-box">
<li *ngFor="let l4 of list4" [cdkDragData]="l4" cdkDrag>
{{l4.nombre}}
</li>
</ol>
</div>
</div>
</div>
</div>
</mat-card>
這是我的下降 function
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);*/
const newArray = event.previousContainer.data.filter(e => e.id !== event.item.data.id);
event.previousContainer.data = newArray;
event.container.data.push(event.item.data)
}
}
我嘗試使用 transferArrayItem 但它沒有工作,因為我得到了錯誤的索引所以我嘗試更改 event.previousContainer.data 和 event.container.data,我使用 event.container.data 但它沒有更改 event.previousContainer.data。
任何想法為什么它不起作用? 提前致謝
您的代碼幾乎一切都很好。
問題是,由於所有帶有cdkDropList
指令的<div>
容器都沒有子容器,它們的高度為零,因此沒有可以丟棄元素的區域。
一種可能的解決方案是將 cdkDropList 移動到更高的位置,例如<div class="example-container">
或者如果您不希望標題(如(+) Talento más desarrollado</h4>
)觸發拖動事件,那么您需要在下面提供一些高度,以便可以將項目拖到那里。
<div class="results">
<div class="talents">
<div class="example-container" cdkDropList
#doneList="cdkDropList"
[cdkDropListData]="list2"
[cdkDropListConnectedTo]="[intermedio, menos]"
class="example-list"
(cdkDropListDropped)="drop($event)"
>
<h4>(+) Talento más desarrollado</h4>
<!-- Probably no need for this div then !-->
<div>
<ol class="example-box">
<li *ngFor="let item of list2" [cdkDragData]="item" cdkDrag>
{{item.name}}
</li>
</ol>
</div>
</div>
</div>
使用這種方法, CdkDragDrop
事件的previousIndex 總是等於“圖像”數組的長度。 我認為可能需要使用CdkDropListGroup
,但將<ngb-carousel>
與 DragDropModule 結合起來似乎是一個問題。 如果一起使用,則 DragDropModule 無法正確識別拖動項的索引。
就像我預期的那樣,如果簡單地列出圖像,那么索引是正確的:
沒有 ngb-carousel - stackblitz 示例。
您的示例中的另一個問題是,可拖動項目應該是 HTML 元素的直接子元素,並帶有 angular cdkDropList 指令。 否則在拖動第二個元素時會出現以下錯誤:
錯誤:無法在“節點”上執行“insertBefore”:要插入新節點的節點不是該節點的子節點。
說了這么多,現在讓我們嘗試使用這些知識並將這段代碼重構為一個工作示例。
首先我們的模板:
<div class="talents">
<div class="example-container" >
<h4>(+) Talento más desarrollado</h4>
<ol class="example-box" cdkDropList
#doneList="cdkDropList"
[cdkDropListData]="list2"
[cdkDropListConnectedTo]="[intermedio, menos]"
(cdkDropListDropped)="drop($event)">
<li *ngFor="let item of list2" [cdkDragData]="item" cdkDrag>
{{item.name}}
</li>
</ol>
</div>
</div>
現在一些 CSS:
.example-box:empty {
height:50px;
border: 5px dashed #cecece;
}
.example-box:empty:hover:after {
content: 'Drag & Drop items here';
color: #aeaeae;
font-weight: bold;
font-size: 18px;
width:50%;
position: relative;
left:25%;
top:5px;
}
通過在沒有子元素的元素上設置高度,我們創建了一個拖放區。 添加邊框和文本是一個很好的用戶體驗設計,它讓我們的最終用戶知道,項目可以被拖到給定的區域。
最后但同樣重要的是 TypeScript:
drop(event: CdkDragDrop<any>) {
// indexes are wrong due to ngb-carousel
if (event.previousContainer === event.container) {
// this is okay, no moving around in ngb-carousel, since it always displays one element;
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
let previousIndex = event.previousIndex;
const element = event.previousContainer.element.nativeElement;
const id = element.getAttribute('id');
// Only indexes of items dragged from carousel needs to be fixed
if (id === this.carouselContainerId) {
previousIndex = event.previousContainer.data.indexOf(event.item.data);
}
transferArrayItem(event.previousContainer.data,
event.container.data,
previousIndex,
event.currentIndex);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.