序章

Angular Component Development Kit (CDK)の@angular/cdk/drag-dropパッケージは、完全な柔軟性を備えたドラッグアンドドロップインターフェイスを簡単に作成する機能を提供します。 車輪の再発明をしなくても、複雑なドラッグアンドドロップインターフェイスを簡単に作成できるAPIを提供します。

この投稿では、CDKを使用してAngularでドラッグアンドドロップを開始するために必要なことについて簡単に説明します。

プロジェクトの設定

まず、CDK自体のパッケージがプロジェクトに追加されていることを確認します。

  1. npm install @angular/cdk

または、Yarnを使用します。

  1. yarn add @angular/cdk

Angularが提供するドラッグアンドドロップ機能にAPIを使用するには、次のようにDragDropModuleをアプリモジュールにインポートします。

app.module.ts
import { DragDropModule } from '@angular/cdk/drag-drop';

その後、インポートのリストにも追加します。

app.module.ts
imports: [
  DragDropModule
]

ドラッグアンドドロップインターフェイスの実装

この投稿の一部として作成するインターフェースは次のとおりです。

Animated gif of drag and drop interface.

4つのタスクトラッカーを備えたドラッグアンドドロップインターフェイス

したがって、すべてのAPIが利用可能になったので、DragDropModuleによって提供されるすべてのディレクティブとモジュールを使用できます。これを使用して、4つのタスクトラックIn Progress[を作成します。 X172X]、D-Done、およびQA Pass

注:ここでは、mat-cardおよびmat-card-contentコンポーネントを使用してタスクを示しています。 これを使用するには、プロジェクトに AngularMaterialも追加する必要があります。

これが最初のドラッグアンドドロップの例です:

app.component.html
<!-- 4 Task trackers are there named "Todo", "In Progress", "D-Done", and "QA-Pass" -->

<div class="board">
  <div class="card-list mat-elevation-z1" *ngFor="let track of tracks; let i=index">

    <h2 cdkDragHandle class="mat-h2">{{track.title}}</h2>

    <div class="card-list-content" cdkDropList [id]="track.id" [cdkDropListData]="track.tasks" [cdkDropListConnectedTo]="trackIds"
      (cdkDropListDropped)="onTaskDrop($event)" [ngStyle]="{'background-color': trackColor[i]}">

      <mat-card style="margin: 2%;" *ngFor="let task of track.tasks" cdkDrag>
        <!-- Use the mat-card-content to add the proper spacing. -->
        <mat-card-content>
          <h2>{{task.title}}</h2>
          {{task.description}}
        </mat-card-content>
      </mat-card>
    </div>

  </div>
</div>

以下は、トラッカーとタスクをレンダリングするために使用しているデータです。

[
  {
    "title": "Todo",
    "id": "todo",
    "tasks": [
      {
        "id": "first-task",
        "title": "First Task",
        "description": "This is my first task"
      }
    ]
  },
  {
    "title": "In Progress",
    "id": "inprogress",
    "tasks": [
      {
        "id": "seconf-task",
        "title": "Second Task",
        "description": "This is my first task"
      }
    ]
  },
  {
    "title": "D-Done",
    "id": "ddone",
    "tasks": [
      {
        "id": "third-task",
        "title": "Third Task",
        "description": "This is my first task"
      }
    ]
  },
  {
    "title": "QA Pass",
    "id": "qapass",
    "tasks": [
      {
        "id": "fourth-task",
        "title": "Fourth Task",
        "description": "This is my first task"
      }
    ]
  }
]
  • cdkDropListディレクティブは、ドラッグ可能なアイテムのセットをラップするコンテナーに適用されます。 cdkDropList要素を追加して、要素をドロップできる場所を制限できます。 この例では、Task Tracksになります。
  • cdkDropListディレクティブには多くのプロパティがあり、cdkDropListDataはその1つであり、コンテナーにデータを任意に追加するために使用されます。 この例では、データとしてタスクトラックを添付しています。
  • cdkDropListDroppedは、ユーザーがコンテナ内にアイテムをドロップしたときに発行されるイベントです。 この例では、タスクがタスクトラック内にドロップされるたびに、onTaskDrop($event)メソッドが呼び出されます。

ドロップイベントを処理するためのメソッドの例を次に示します。

app.component.ts
onTaskDrop(event: CdkDragDrop<Task[]>) {
  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);
  }
}

メソッドの一部としての条件ステートメントに注意してください。 宛先コンテナーが前のコンテナーと異なる場合は、指定されたタスクをターゲットデータ配列に転送する必要があります。 これは、タスクが別のトラックにドロップされた場合に発生します。

以上です! これで、ドラッグアンドドロップ機能が機能するようになりました。

結論

Angularの公式ドラッグアンドドロップのドキュメントを確認して、何ができるかを深く掘り下げてください。

このサンプルプロジェクトの完全なソースコードは、このリポジトリGitHubにあります。