Angular - Drag data
本文透過DragEvent與Angular MVVM的特性,實現表格資料拖動以變更資料排序。
- 設定資料列
tr可拖動draggable="true"。
<tr *ngFor="let data of dataSet; let i = index;"
[ngClass]="{'drag-enter' : targetIndex == i}"
draggable="true"
(dragstart)="dragstart(data,i)"
(dragenter)="dragenter(data,i)"
(dragend)="dragend()">
<td *ngFor="let field of dataField">
{{ data[field.value] }}
</td>
</tr>
- 在拖動開始時,紀錄目標移動資料
targetData與其索引targetIndex。
targetData: undefined;
targetIndex: number = -1;
dragstart(data: any, rowIndex: number) {
this.targetData = data;
this.targetIndex = rowIndex;
}
- 拖動進行時,取得進入的資料
enterData與其索引enterIndex交換目標資料targetData與進入資料,並比較targetIndex與enterIndex的大小,判段目標移動方向。
- 往下拖動:
targetIndex < enterIndex。每當目標往下移動,將前一項資料enterIndex-1替換成進入資料enterData;進入資料enterIndex替換成目標資料targetData。最後紀錄目標資料位置targetIndex為enterIndex。 - 往上拖動:
targetIndex > enterIndex。每當目標往上移動,將後一項資料enterIndex+1替換成進入資料enterData;進入資料enterIndex替換成目標資料targetData。最後紀錄目標資料位置targetIndex為enterIndex。
/* switch enterData and targetData */
dragenter(enterData: any, enterIndex: number) {
if(enterIndex > this.targetIndex) { // drag direction: ↓
this.dataSet[enterIndex-1] = enterData;
this.dataSet[enterIndex] = this.targetData;
this.targetIndex = enterIndex;
}
else if(enterIndex < this.targetIndex) { // drag direction: ↑
this.dataSet[enterIndex+1] = enterData;
this.dataSet[enterIndex] = this.targetData;
this.targetIndex = enterIndex;
}
}
- 隱藏目標移動資料。
tr.drag-enter {
opacity: 0;
}
[ngClass]="{'drag-enter' : targetIndex == i}"
- 當拖動結束時,顯示該資料。
dragend() { this.targetIndex = -1; }