Angular 如何为源和汇滴列表设置不同的CKDDRAGG占位符?

Angular 如何为源和汇滴列表设置不同的CKDDRAGG占位符?,angular,angular-material,drag-and-drop,angular-material2,Angular,Angular Material,Drag And Drop,Angular Material2,我正在使用Angular material的模块来移动一些元素 更具体地说,我有多个cdkDropLists,每个中有一个cdkDrag: <div *ngFor="let l of lists"> <div cdkDropList [cdkDropListConnectedTo]="all_lists"> <div cdkDrag> content </div> </div> </div>

我正在使用Angular material的模块来移动一些元素

更具体地说,我有多个
cdkDropList
s,每个中有一个
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>

内容
占位符内容
但是,当我执行此操作时,占位符内容将显示在缺少(当前正在拖动)元素(源列表)的位置以及其新位置(接收器列表)的位置。我希望能够为sink列表保留默认行为(显示根元素aka
content
),并且仅为源列表保留占位符

尽管我无法区分这两个地方,因为即使在“接收器”位置,也似乎是源代码的“元素”HTML正在显示(这有点道理,因为占位符是
cdkDrag
的属性,而不是
cdkDropList

如何使用不同的占位符替换元素的原始位置和新位置

斯塔克闪电战


直觉:(多个)列表是牌组,当将一张牌从a移动到B时,我在a组中看到第二张到顶部(自定义占位符)的牌,但当我将顶部a的牌悬停在B上时,我在那里看到了top-A卡。

如果我正确理解了您的问题,您希望仅在拖动到另一个列表时显示自定义占位符,并在同一列表中拖动时显示默认占位符

要检测源列表外的移动,可以使用
cdkDragEntered
事件,该事件可在项目从外部拖动到列表内时触发。在事件数据中,您拥有您输入的列表信息以及有关正在拖动的项目的所有信息。该项包含其当前所属列表的信息。这意味着,当我们输入的列表与项目列表不同时,已输入另一个列表。获得此信息后,您可以根据此信息更改占位符内显示的内容

我已将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;
  }
}
导出类CdkDragDropConnectedSortingGroupExample{
待办事项=[
“开始工作”,
“拿食品杂货”,
“回家”,
“入睡”
];
完成=[
“起来”,
“刷牙”,
“洗个澡”,
];
另一个=[
“检查电子邮件”,
“走狗”
]
lists=[this.todo,this.done,this.other];
public draggingOutsideSourceList:boolean=false;
drop(事件:CdkDragDrop){
if(event.previousContainer==event.container){
moveItemInArray(event.container.data、event.previousIndex、event.currentIndex);
}否则{
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
事件(当前索引);
}
this.draggingOutsideSourceList=false;//始终在拖放完成后重置
}
OnCDKdragEnter(事件:CdkDragEnter){
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>

{{item}}
仅接收器列表中的自定义占位符内容
如您所见,我创建了三个列表使用
cdkDragEntered
事件通过设置模板中使用的
draggingOutsideSourceList
属性来选择要在占位符中显示的内容,来确定拖动是在源列表的外部还是内部


这里也是一个你可以看到它工作的地方。

如果你能围绕它创建一个stackblitz会更好。像这样的吗?谢谢@David给我们举个例子。它朝着好的方向发展:我需要能够在两个方向上移动项目:因此,当我从底部移动到顶部时,“自定义占位符”应该只显示在顶部(目前根本不显示),而如果我从顶部移动到底部,它应该只显示在底部(目前显示)。我也不能用这种方式预先指定CSSE,因为我事先不知道列表的数量(
div*ngFor=“let l of list”
)。是的,作为poc,我只使用了一种方式,但对于多个列表,应该使用相同的方式。您能否根据自己的要求创建一个包含多个列表的stackblitz?参见示例。我试图使你的代码适应这两种方式,但没有成功。