Angular 7 组件之间如何使用cdkDropList?

How to use Angular 7 cdkDropList between components?

我在屏幕左侧的 mat-list 组件中有一个项目(学生)列表(一般列表)。我的屏幕右侧还有一个 class-room 组件列表。 在每个 class-room 组件中,有一个 mat-list 学生。

我希望能够使用新的 Drag&Drop API of angular material

将学生从通用列表拖到任何 class-room 组件中包含的学生列表之一

伪代码如下所示:

<mat-list #studentsList="cdkDropList" cdkDropList [cdkDropListData]="students">
  <mat-list-item cdkDrag *ngFor="let student of studentes">
    {{student.name}}
  </mat-list-item>
</mat-list>

<div class="right-panel>
  <app-class-room *ngFor="let cr of classRooms" [classRoom]="cr"></app-class-room>
</div>

显然,我不能在通用列表中使用 [cdkDropListConnectedTo] 输入,因为我无权访问 Class-room 组件内的学生列表。我该如何进行?

您可以使用字符串而不是 API documentation 中提到的引用:

@Input('cdkDropListConnectedTo') connectedTo: (CdkDropList | string)[] | CdkDropList | string

Other draggable containers that this container is connected to and into which the container's items can be transferred. Can either be references to other drop containers, or their unique IDs.

我使用所有可放置元素 ID 的列表做了一个示例。

allDropLists = [ 'studentsList', ...this.classRooms
 .map(_ => _.name)];

我将其作为输入传递给 ClassRoomComponent :

<app-class-room
    *ngFor="let classRoom of classRooms" 
    [classRoom]="classRoom" [allDropLists]="allDropLists">

The complete running example is here.

您也可以使用 CdkDropListGroup 作为父元素 div,任何子元素都将成为该组的一部分,无论它有多少或在哪里形成(ngFor 等...),您都可以然后将 div 放在 CSS 视图的对面。如果您正在动态创建 DropLists en masse

我想扩展之前的答案,因为我找不到适用于我的场景的示例。 请注意,我简化了这个示例以强调重要的部分(连接所需的列表)。

“实际传输逻辑”是由(cdkDropListDropped)="onDrop($event)"实现的。 确实有一个basic example

1。通过 cdkDropListConnectedTo

连接不同组件中的特定 cdkDropLists

有时我们不想连接所有子组件,而只想连接某些子组件。 为此,我们将使用 cdkDropListConnectedTo,但我们必须为每个 cdkDropList 提供一个唯一的 ID。问题是它不是通常的 HTML id。

走错路

<component1 id="component1" cdkDropList> // <- NO!

我们会收到此类错误

CdkDropList could not find connected drop list with id component1

正确的方式

documentation 指出 cdkDropList 有一个专用于 id@Input() 属性。 因此连接列表的正确方法是:

<component1 [id]="'component1'" [cdkDropListConnectedTo]="'component2'" cdkDropList></...>
<component2 [id]="'component2'" cdkDropList></...>
<component3 [id]="'component3'" cdkDropList></...>

您现在只能从 component1 拖动到 component2。

请注意,此示例中的 id 是一个字符串。 我们必须将字符串包装在 ' ' 中以将它们传递给 @Input()here's 一个小指南,以防您不熟悉它)。

2。使用 cdkDropListGroup 指令连接所有 cdkDropLists

cdkDropListGroup 添加到父元素会连接所有子元素并允许在它们之间拖动。 cdkDropListGroup documentation.

<section cdkDropListGroup>
    <component1 cdkDropList></component1>
    <component2 cdkDropList></component2>
    <component3 cdkDropList></component3>
</section>

每个项目都可以在组件 1、2 和 3 之间转移。


编辑:这是一个包含两个组件的 working example