Angular2でドラッグアンドドロップ(DnD)を実装するためのライブラリとして、ng2-dndがあります。
HTML5のDnD処理に準拠した形で実装されているライブラリで、簡単にDnDが実装できます。
ng2-dndのインストール
npmコマンドでインストールできます。
npm install ng2-dnd --save
ng2-dndを使う準備
最近、Angular2のrc5がリリースされ、NgModuleに使用するディレクティブやプロバイダーを記述できるようになりましたので、そちらのやり方でエントリポイントのtsファイルを記述してみます。
import "core-js";
import "rxjs/Rx";
import "zone.js/dist/zone";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { Component, NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { DND_PROVIDERS, DND_DIRECTIVES } from "ng2-dnd";// v1.13.0より前 "ng2-dnd/ng2-dnd";
@NgModule({
declarations: [
AppBodyComponent,
DND_DIRECTIVES
],
imports: [BrowserModule],
bootstrap: [AppBodyComponent],
providers: [DND_PROVIDERS]
})
class AppModule {
}
platformBrowserDynamic().bootstrapModule(AppModule);
ng2-dndを使うためには、declarationsにDND_DIRECTIVES、providersにDND_PROVIDERSを記述します。
index.htmlはこんな感じ。
webpackを使っているので、読込はbundle.jsだけ。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello DnD</title>
</head>
<body>
<app-body>Loading…</app-body>
</body>
<script src="./js/bundle.js"></script>
</html>
ng-dndの記述
めんどいので、エントリポイントと同じapp.tsに今回は記述します。
@Component({
selector: "app-body",
template: `
<!-- ドラッグ側 -->
<div *ngFor="let drag of drags"
dnd-draggable [dragEnabled]="true"
[dragData]="drag">
<div>
<div>{{drag}}</div>
</div>
</div>
<!-- ドロップ側 -->
<div
dnd-droppable (onDropSuccess)="drops.push($event.dragData)">
Place to drop
</div>
<div *ngFor="let drop of drops">
{{drop}}
</div>
`
})
class AppBodyComponent {
public drags: Array<string> = [
"Hello World!",
"Hello Angular2",
"Hello DnD"
];
public drops: Array<string> = [];
}
ドラッグ側では、dnd-draggable [dragData]="drag"
を記述。
[dragData]の右辺は、ドロップ側に渡されるデータ($event.dragDataに格納されるデータ)。
ドロップ側では、dnd-droppable (onDropSuccess)="drops.push($event.dragData)"
を記述。
(onDropSuccess)の右辺は、ドロップ時の処理を設定。今回は直接処理を記述していますが、関数化して記述するのが一般的かと。
ドラッグ側、ドロップ側共にほかにも設定可能な項目がいっぱいありますが、説明は省略。
結果
webpackを使って、tsファイルをbundle化して実行すると、次の画像のようになります。
上の3つの文字列をPlace to dropにドロップすると、下の文字列が増えていきます。
カーソルが映ってないですが、右側にある半透明な部分がドラッグ中の画像。