我正在使用Angular材质的Drag and Drop模块移动一些元素。
更具体地说,我有多个cdkDropList
,每个中都有一个cdkDrag
:
<div *ngFor="let l of lists">
<div cdkDropList [cdkDropListConnectedTo]="all_lists">
<div cdkDrag>
content
</div>
</div>
</div>
每当从列表中移动元素时,我都希望有一个占位符,例如:
<div cdkDrag>
content
<div *cdkDragPlaceholder>
placeholder content
</div>
</div>
但是,在执行此操作时,将显示占位符内容,以替代丢失(当前被拖动)的元素(源列表)以及其新位置(接收者列表)。我希望能够保留接收器列表的默认行为(显示根元素aka content
),并且仅将占位符用于源列表。
不过,我无法区分这两个位置,因为即使在“接收器”位置,也似乎显示了源元素的HTML(这在一定程度上是有意义的,因为占位符是cdkDrag
的属性,而不是cdkDropList
)。
如何在元素的原始位置和新位置之间使用不同的占位符?
Stackblitz example。
直觉:(多个)列表是一副纸牌,当将一张纸牌从A移到B时,我在A纸牌中看到了倒数第二个(自定义占位符)卡,但是当我将A纸牌悬停时在B上方,我看到那里的A顶卡。
如果我正确理解了您的问题,您只想在拖动到另一个列表时显示自定义占位符,而在同一列表中拖动时才显示默认占位符。
要检测源列表之外的移动,您可以使用cdkDragEntered
事件,该事件会在项目从外部拖到列表内部时触发。在CdkDragEnter事件数据中,您具有输入的信息列表以及有关所拖动项目的所有信息。该项目包含其当前所属列表的信息。这意味着当我们输入的列表与项目列表不同时,已经输入了另一个列表。获得此信息后,您可以根据此信息更改占位符内显示的内容。
我已将您的StackBlitz示例更改为这种方法。
组件代码:
export class CdkDragDropConnectedSortingGroupExample {
todo = [
'Get to work',
'Pick up groceries',
'Go home',
'Fall asleep'
];
done = [
'Get up',
'Brush teeth',
'Take a shower',
];
another = [
'Check e-mail',
'Walk dog'
]
lists = [this.todo, this.done, this.another];
public draggingOutsideSourceList: boolean = false;
drop(event: CdkDragDrop<string[]>) {
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);
}
this.draggingOutsideSourceList = false; // always reset after drag drop finishes
}
onCdkDragEntered(event: CdkDragEnter<string>) {
this.draggingOutsideSourceList = event.container !== event.item.dropContainer;
}
}
模板:
<div cdkDropListGroup>
<div class="example-container todoList" *ngFor="let list of lists">
<div cdkDropList [cdkDropListData]="list" class="example-list" (cdkDropListDropped)="drop($event)">
<div cdkDrag *ngFor="let item of list" (cdkDragEntered)="onCdkDragEntered($event)">
<ng-template #itemTpl>
<div class="example-box">{{item}}</div>
</ng-template>
<div *cdkDragPlaceholder>
<div *ngIf="draggingOutsideSourceList; else itemTpl" class="customPlaceHolder">
Custom placeholder content only in sink list
</div>
</div>
<ng-container *ngTemplateOutlet="itemTpl"></ng-container>
</div>
</div>
</div>
</div>
您可以看到,我创建了三个列表,使用cdkDragEntered
事件通过设置模板中使用的draggingOutsideSourceList
属性来选择拖动显示是在源列表的外部还是内部,以选择要在占位符中显示的内容。
这里也是link to a fork of your StackBlitz,您可以在其中看到它的工作。