Edited at

Angular v7のDragDropModuleを使ってTrelloっぽいの作ってみた

More than 1 year has passed since last update.

Angular 7.0.0がリリースされましたね 🎉

CDKにDrag and DropのModuleが追加されたので触ってみました。

ドラッグ・アンド・ドロップの機能って自前で開発すると結構めんどくさかったのが、めちゃくちゃ簡単に実装できました👏楽しい👏

DEMO


やったこと



  • app.module.tsDragDropModule をimportする


app.module.ts

import { NgModule } from '@angular/core';

import { BrowserModule } from '@angular/platform-browser';
import { DragDropModule } from '@angular/cdk/drag-drop';

import { AppComponent } from './app.component';

@NgModule({
imports: [
BrowserModule,
DragDropModule
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }




  • app.component.tsCdkDragDrop, moveItemInArray, transferArrayItem をimportする

  • ドロップ時のメソッドを定義する


    • event発生したときに、 container が移動前と同じ配列か違う配列かを判定して、 moveItemInArray()transferArrayItem() を実行する




app.component.ts

import { Component } from '@angular/core';

import {
CdkDragDrop,
moveItemInArray,
transferArrayItem
} from '@angular/cdk/drag-drop';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public todo = [
'働く',
'映画を見る',
'掃除する',
'洗濯する',
'飲みに行く',
'買い物に行く',
'家に帰る',
'散歩する',
]

public doing = [
'サッカーする',
'野球する',
'バスケする',
'テニスする',
]

public done = [
'本を読む',
'歯を磨く',
'昼寝する',
'メールチェック',
'犬と遊ぶ'
]

public drop(event: CdkDragDrop<string[]>): void {
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);
}
}
}




  • cdkDropListcdkDrag 要素セットの親要素に追加する


  • #todoList="cdkDropList" ←のように cdkDropListへの参照をテンプレート変数化する


  • [cdkDropListConnectedTo]="[doneList]"


    • 移動先としてつなぎたい cdkDropList の参照を指定する




  • cdkDropListDropped イベントは、ドラッグが終了した時に発火するので、 app.component.ts で定義しておいた drop() メソッドを使う


app.component.html

<section class="container">

<h1>MY TASKS</h1>
<div class="cards">
<section class="card">
<h2>
TODO
</h2>
<ul cdkDropList
#todoList="cdkDropList"
[cdkDropListData]="todo"
[cdkDropListConnectedTo]="[doingList, doneList]"
class="list"
(cdkDropListDropped)="drop($event)">
<li class="item" *ngFor="let item of todo" cdkDrag>{{item}}</li>
</ul>
</section>
<section class="card">
<h2>
DOING
</h2>
<ul cdkDropList
#doingList="cdkDropList"
[cdkDropListData]="doing"
[cdkDropListConnectedTo]="[todoList, doneList]"
class="list"
(cdkDropListDropped)="drop($event)">
<li class="item" *ngFor="let item of doing" cdkDrag>{{item}}</li>
</ul>
</section>
<section class="card">
<h2>
DONE
</h2>
<ul cdkDropList
#doneList="cdkDropList"
[cdkDropListData]="done"
[cdkDropListConnectedTo]="[todoList, doingList]"
class="list"
(cdkDropListDropped)="drop($event)">
<li class="item" *ngFor="let item of done" cdkDrag>{{item}}</li>
</ul>
</section>
</div>
</section>


さいごに

実際の機能開発だと、もっとやることあると思いますが、とりあえずUIはこれだけで実装できました。

ライブラリとか使ったり、自前で開発する必要がなさそうなので、とても良いですね。


cf.