前言:最近项目要实现一个拖拽功能,我在网上开始了各类搜寻,虽然后面因为数据原因舍弃了拖拽的这一需求,但是为了不辜负最近的研究,还是来记录一下。

场景需求:面试预约选时间节点,候选人之间是可以相互交换的,但是局限于面试方向相同的候选人才能相互拖拽(拖拽后即表示两个候选人之间交换面试时间)。本来此种场景上图更为明确,奈何公司只限于内网开发,上传不了图片,嘤嘤嘤。。。

参考文章:https://www.cnblogs.com/starof/p/10662027.html

正文:

draggable是H5新增的属性,true表示可以拖拽,false表示不能拖拽。在拖拽过程中分别有两个元素:被拖动元素与目标元素。

被拖动元素相关的事件:

  • ondragstart:按下鼠标并开始移动时触发该事件。
  • ondrag:在start事件触发后被触发,并在鼠标移动过程中不停被触发。
  • ondragend:当拖动停止触发(无论把元素放到拖放目标上还是在无效目标上)

目标元素相关的事件:

  • ondragenter:被拖动元素进入目标时触发。
  • ondragover:被拖动元素在目标元素上移动时被触发。
  • ondragleave:被拖动元素离开目标时触发,即拖到无效目标时。
  • ondrop:被拖动元素被放置在目标上时被触发。

注意:默认情况下目标元素是不允许被放置的,所以不会触发drop事件。这时需要在ondragover中阻止默认行为才能成为被允许放置的目标。

对于angular、vue等依赖组件开发的框架,最好把draggable封装成指令去实现功能。(实施步骤与参考文章无异,直接上代码啦,其他不赘述)具体步骤:

1.新建directives指令文件夹

2.新建拖拽文件夹directives/drap-drop

3.新建drap指令文件directives/drag-drop/drag.directive.ts

4.新建drop指令文件directives/drag-drop/drop.directive.ts

5.因为涉及数据交换,所以要新建一个services来传递数据,directives/directives.services.ts

6.新建directives/directives.module.ts

7.在公共模板中引入DirectiveModule

8.引用

directives.module.ts

import { NgModule } from '@angular/core';
import { DragDirective } from './drag-drop/drag.directive';
import { DropDirective } from './drag-drop/drop.directive';
import { DragDropService } from './drag-drop/drag-drop.service';
@NgModule({
declarations: [DragDirective, DropDirective],
exports: [DragDirective, DropDirective],
providers:[DragDropService]
})
export class DirectiveModule { }

drag.directive.ts

import { Directive,HostBinding, HostListener, Host, ElementRef, Renderer2, Input,Output,EventEmitter } from '@angular/core';
import {DragDropService} from './drag-drop.service';
@Directive({
selector: '[app-draggable][dragTag][dragData][draggedClass]'
})
export class DragDirective {
private _isDraggble = false;
/*给标签设置draggable属性
*true-能拖拽
*false-不能拖拽
*/
@Input('app-draggable')
set isDraggable(value:boolean){
this._isDraggble=value;
this.rd.setAttribute(this.el.nativeElement,'draggable',`${value}`);
}
get isDraggable(){
return this._isDraggble;
} //拖拽开始时添加的class
@Input()
draggedClass:string; //给拖拽的元素定义dragTag标识(目标元素也会设置一个标识,用于判断该元素是否能拖到目标元素)
@Input()
dragTag:any; //给DragDropservice传递的数据(即目标元素的数据)
@Input()
dragData:any //判断开始/结束拖拽时,部分区域的元素是不能设置为拖拽目标的(给不能拖拽的区域设置背景色)
@Output()
dragStart = new EventEmitter<any>();
@Output()
dragEnd = new EventEmitter<any>(); constructor(private el:ElementRef, private rd:Renderer2,private service:DragDropService) { } @HostListener('dragstart', ['$event'])
ondragstart(ev:Event){
//判断drag元素是不是指令应用的元素发起的
if(this.el.nativeElement===ev.target){
this.rd.addClass(this.el.nativeElement, this.draggedClass);//往el上增加一个class
//进入时候给service传递上数据
this.service.setDragData({tag:this.dragTag,data:this.dragData});
ev['dataTransfer'].setData('tag',this.dragTag);//兼容firefox,用来设置拖放操作的drag data到指定的数据和类型
this.dragStart.emit(this.dragTag);
} } @HostListener('dragend', ['$event'])
ondragend(ev:Event){
if(this.el.nativeElement===ev.target){
this.rd.removeClass(this.el.nativeElement, this.draggedClass);
this.dragEnd.emit(this.dragTag);
}
}
}

drop.directive.ts

import { Directive, HostListener, ElementRef, Renderer2, Input, Output, EventEmitter  } from '@angular/core';
import { DragDropService, DragData } from './drag-drop.service';
import { take } from 'rxjs/operators'; @Directive({
selector: '[dropTag]'
})
export class DropDirective {
/*拖拽至目标元素时发射的事件*/
@Output()
dropped = new EventEmitter<DragData>(); /*设定目标区域的标识*/
@Input()
dropTag:any; private data$;
constructor(private el:ElementRef, private rd:Renderer2,private service:DragDropService) {
this.data$ = this.service.getDragData().pipe(take(1));
} @HostListener('dragenter', ['$event'])
onDragEnter(ev:Event){
//判断drag元素是不是指令应用的元素发起的
if(this.el.nativeElement===ev.target){
this.data$.subscribe(dragData=>{
if(dragData && this.dropTag == dragData.tag){ }
});
}
} //dragover允许进行data transfer的一些特效
@HostListener('dragover', ['$event'])
onDragOver(ev:Event){
//需要支持多级拖拽,所以要防止事件冒泡
ev.preventDefault();
ev.stopPropagation();
if(this.el.nativeElement===ev.target){
this.data$.subscribe(dragData=>{
if(dragData && this.dropTag == dragData.tag){
this.rd.setProperty(ev,'dataTransfer.effectAllowed','all');
this.rd.setProperty(ev,'dataTransfer.fropEffect','move');
}else{
this.rd.setProperty(ev,'dataTransfer.effectAllowed','none');
this.rd.setProperty(ev,'dataTransfer.dropEffect','none');
}
});
}
} @HostListener('dragleave', ['$event'])
onDragLeave(ev:Event){
ev.preventDefault();
ev.stopPropagation();
if(this.el.nativeElement===ev.target){
this.data$.subscribe(dragData=>{
if(dragData && this.dropTag == dragData.tag){ }
});
} } @HostListener('drop', ['$event'])
onDrop(ev:Event){
ev.preventDefault();
ev.stopPropagation();
if(this.el.nativeElement===ev.target){
this.data$.subscribe(dragData => {
if(dragData && this.dropTag == dragData.tag){
this.dropped.emit(dragData);//drop的时候把dragData发射出去
this.service.clearDragData(); //drop的时候把data clear掉,否则会影响下一次拖拽
}
});
} }
}

directives.services.ts

import { Injectable } from '@angular/core';
import { Observable,BehaviorSubject } from 'rxjs'; //数据结构
export interface DragData{
tag:string; //多重拖拽的话是哪一级拖拽,用户自己保证唯一性,不能重复
data:any; //传递的数据
} @Injectable({
providedIn: 'root'
})
export class DragDropService {
//用BehaviorSubject总能记住上一次的值
private _dragData = new BehaviorSubject<DragData>(null);
setDragData(data:DragData){
this._dragData.next(data);
} getDragData():Observable<DragData>{
return this._dragData.asObservable();
} clearDragData(){
this._dragData.next(null);
}
constructor() { }
}

公共模板common.module.ts中引入DirectiveModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgZorroAntdModule} from '../zorro/ng-zorro-antd.module';
import {NzPaginationUpComponent} from "./nzPaginationUp.component";
import {DirectiveModule} from "./directives/directives.module";
@NgModule({
imports: [
CommonModule,
FormsModule,
NgZorroAntdModule,
DirectiveModule
],
declarations: [
NzPaginationUpComponent, ],
exports: [
NzPaginationUpComponent,
DirectiveModule ],
providers: [LoadingBarService, DateHelper]
})
export class CoreFrameCommonModule { }

引用:

test.component.html

<table>
<tr>
<td class="b-n-t b-n-l b-n-b b-n-r" width="80"></td>
<td class="b-n-t b-n-l b-n-b" width="50"></td>
<ng-template ngFor let-item [ngForOf]="menuContent[0].dateArr">
<td>{{item.week}}</td>
</ng-template>
</tr>
<tr>
<td class="b-n-t b-n-l b-n-r"></td>
<td class="b-n-t b-n-l"></td>
<ng-template ngFor let-item [ngForOf]="menuContent[0].dateArr">
<td>{{item.date}}</td>
</ng-template>
</tr>
<tr *ngFor="let group of menuContent">
<td>{{group.groupName}}</td>
<!--时间点-start-->
<td>
<div class="time-box" *ngFor="let etc of group.dateArr[0].etc">
<ng-template ngFor let-dateItem [ngForOf]="etc.detail">
<div class="time-item">{{dateItem.time}}</div>
</ng-template>
</div>
</td>
<!--时间点-end-->
<!--坑-start-->
<ng-template ngFor let-item0 [ngForOf]="group.dateArr">
<td>
<div class="name-box" [ngClass]="{'no-drop': dragCurrentDirect && item1.direct != dragCurrentDirect}" *ngFor="let item1 of item0.etc">
<ng-template ngFor let-item2 [ngForOf]="item1.detail">
<div class="name-item">
<div [app-draggable]="true"
draggedClass="drag-start"
[dragTag]="item2['direct']"
[dragData]="item2"
(dragStart)="moveStart($event)"
(dragEnd)="moveEnd($event)"
[dropTag]="item2['direct']"
(dropped)="handleMove($event,item2)">{{item2.name}}</div>
</div>
</ng-template>
</div>
</td>
</ng-template>
<!--坑-end-->
</tr>
</table>

test.component.scss

.box{
padding:20px;
border:2px solid #ddd;
div{
margin-bottom:10px;
height:100px;
text-align:center;
line-height:100px;
background:#fff;
border-radius:4px;
}
}
table{
width:800px;
table-layout:fixed;
border-collapse:collapse;
background:#fff;
.time-item,.name-item{
line-height:30px;
height:30px;
border-bottom:1px solid #999;
}
.time-box:last-child .time-item:last-child{border-bottom:0;}
.name-box:last-child .name-item:last-child{border-bottom:0;}
.name-item{
cursor:pointer;
div{height:30px;}
.drag-start{
color:#fff;
background:#c8152d;
opacity:.8;
}
}
}
th,td{
border:1px #525152 solid;
text-align:center;
line-height:40px;
}
.no-drop{background-color:#ddd;}
.b-n-t{border-top:1px solid transparent}
.b-n-l{border-left:1px solid transparent}
.b-n-b{border-bottom:1px solid transparent}
.b-n-r{border-right:1px solid transparent}

test.component.ts

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

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
dragCurrentDirect:string;//用于判断拖拽的是否是有效的目标
menuContent=[
{groupName:'A组',dateArr:[
{week:'星期一',date:'11月4日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张1',sapId:'001',direct:'C#',boxId:'1'},
{time:'8:00',name:'张2',sapId:'002',direct:'C#',boxId:'2'},
{time:'8:40',name:'张3',sapId:'003',direct:'C#',boxId:'3'},
{time:'9:00',name:'张4',sapId:'004',direct:'C#',boxId:'4'},
{time:'9:20',name:'张5',sapId:'005',direct:'C#',boxId:'5'},
{time:'9:40',name:'张6',sapId:'006',direct:'C#',boxId:'6'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王1',sapId:'007',direct:'Java',boxId:'7'},
{time:'10:20',name:'王2',sapId:'008',direct:'Java',boxId:'8'},
{time:'11:00',name:'王3',sapId:'009',direct:'Java',boxId:'9'},
{time:'11:20',name:'王4',sapId:'0010',direct:'Java',boxId:'10'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘1',sapId:'0011',direct:'前端',boxId:'11'},
{time:'14:20',name:'刘2',sapId:'0012',direct:'前端',boxId:'12'},
{time:'14:40',name:'刘3',sapId:'0013',direct:'前端',boxId:'13'},
{time:'15:00',name:'刘4',sapId:'0014',direct:'前端',boxId:'14'},
{time:'15:20',name:'刘5',sapId:'0015',direct:'前端',boxId:'15'},
{time:'15:40',name:'刘6',sapId:'0016',direct:'前端',boxId:'16'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周1',sapId:'0011',direct:'Java',boxId:'17'},
{time:'16:20',name:'周2',sapId:'0012',direct:'Java',boxId:'18'},
{time:'16:40',name:'周3',sapId:'0013',direct:'Java',boxId:'19'},
{time:'17:00',name:'周4',sapId:'0014',direct:'Java',boxId:'20'}
]}
]},
{week:'星期二',date:'11月5日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张111',sapId:'0035',direct:'C#',boxId:'21'},
{time:'8:00',name:'张112',sapId:'0036',direct:'C#',boxId:'22'},
{time:'8:40',name:'张113',sapId:'0037',direct:'C#',boxId:'23'},
{time:'9:00',name:'张114',sapId:'0038',direct:'C#',boxId:'24'},
{time:'9:20',name:'张115',sapId:'0039',direct:'C#',boxId:'25'},
{time:'9:40',name:'张116',sapId:'0040',direct:'C#',boxId:'26'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王111',sapId:'0041',direct:'Java',boxId:'27'},
{time:'10:20',name:'王112',sapId:'0042',direct:'Java',boxId:'28'},
{time:'11:00',name:'王113',sapId:'0043',direct:'Java',boxId:'29'},
{time:'11:20',name:'王114',sapId:'0044',direct:'Java',boxId:'30'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘111',sapId:'0045',direct:'前端',boxId:'31'},
{time:'14:20',name:'刘112',sapId:'0046',direct:'前端',boxId:'32'},
{time:'14:40',name:'刘113',sapId:'0047',direct:'前端',boxId:'33'},
{time:'15:00',name:'刘114',sapId:'0048',direct:'前端',boxId:'34'},
{time:'15:20',name:'刘115',sapId:'0049',direct:'前端',boxId:'35'},
{time:'15:40',name:'刘116',sapId:'0050',direct:'前端',boxId:'36'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周111',sapId:'0051',direct:'Java',boxId:'37'},
{time:'16:20',name:'周112',sapId:'0052',direct:'Java',boxId:'38'},
{time:'16:40',name:'周113',sapId:'0053',direct:'Java',boxId:'39'},
{time:'17:00',name:'周114',sapId:'0054',direct:'Java',boxId:'40'}
]}
]},
{week:'星期四',date:'11月7日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张1111',sapId:'0075',direct:'C#',boxId:'41'},
{time:'8:00',name:'张1112',sapId:'0076',direct:'C#',boxId:'42'},
{time:'8:40',name:'张1113',sapId:'0077',direct:'C#',boxId:'43'},
{time:'9:00',name:'张1114',sapId:'0078',direct:'C#',boxId:'44'},
{time:'9:20',name:'张1115',sapId:'0079',direct:'C#',boxId:'45'},
{time:'9:40',name:'张1116',sapId:'0080',direct:'C#',boxId:'46'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王1111',sapId:'0081',direct:'Java',boxId:'47'},
{time:'10:20',name:'王1112',sapId:'0082',direct:'Java',boxId:'48'},
{time:'11:00',name:'王1113',sapId:'0083',direct:'Java',boxId:'49'},
{time:'11:20',name:'王1114',sapId:'0084',direct:'Java',boxId:'50'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘1111',sapId:'0085',direct:'前端',boxId:'51'},
{time:'14:20',name:'刘1112',sapId:'0086',direct:'前端',boxId:'52'},
{time:'14:40',name:'刘1113',sapId:'0087',direct:'前端',boxId:'53'},
{time:'15:00',name:'刘1114',sapId:'0088',direct:'前端',boxId:'54'},
{time:'15:20',name:'刘1115',sapId:'0089',direct:'前端',boxId:'55'},
{time:'15:40',name:'刘1116',sapId:'0090',direct:'前端',boxId:'56'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周1111',sapId:'0091',direct:'Java',boxId:'57'},
{time:'16:20',name:'周1112',sapId:'0092',direct:'Java',boxId:'58'},
{time:'16:40',name:'周1113',sapId:'0093',direct:'Java',boxId:'59'},
{time:'17:00',name:'周1114',sapId:'0094',direct:'Java',boxId:'60'}
]},
]},
{week:'星期五',date:'11月8日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张11111',sapId:'00205',direct:'C#',boxId:'61'},
{time:'8:00',name:'张11112',sapId:'00206',direct:'C#',boxId:'62'},
{time:'8:40',name:'张11113',sapId:'00207',direct:'C#',boxId:'63'},
{time:'9:00',name:'张11114',sapId:'00208',direct:'C#',boxId:'64'},
{time:'9:20',name:'张11115',sapId:'00209',direct:'C#',boxId:'65'},
{time:'9:40',name:'张11116',sapId:'00210',direct:'C#',boxId:'66'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王11111',sapId:'00211',direct:'Java',boxId:'67'},
{time:'10:20',name:'王11112',sapId:'00212',direct:'Java',boxId:'68'},
{time:'11:00',name:'王11113',sapId:'00213',direct:'Java',boxId:'69'},
{time:'11:20',name:'王11114',sapId:'00214',direct:'Java',boxId:'70'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘11111',sapId:'00215',direct:'前端',boxId:'71'},
{time:'14:20',name:'刘11112',sapId:'00216',direct:'前端',boxId:'72'},
{time:'14:40',name:'刘11113',sapId:'00217',direct:'前端',boxId:'73'},
{time:'15:00',name:'刘11114',sapId:'00218',direct:'前端',boxId:'74'},
{time:'15:20',name:'刘11115',sapId:'00219',direct:'前端',boxId:'75'},
{time:'15:40',name:'刘11116',sapId:'00220',direct:'前端',boxId:'76'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周11111',sapId:'00221',direct:'Java',boxId:'77'},
{time:'16:20',name:'周11112',sapId:'00222',direct:'Java',boxId:'78'},
{time:'16:40',name:'周11113',sapId:'00223',direct:'Java',boxId:'79'},
{time:'17:00',name:'周11114',sapId:'00224',direct:'Java',boxId:'80'}
]},
]}
]},
{groupName:'B组',dateArr:[
{week:'星期一',date:'11月4日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'',sapId:'',direct:'C#',boxId:'81'},
{time:'8:00',name:'',sapId:'',direct:'C#',boxId:'82'},
{time:'8:40',name:'张13',sapId:'0017',direct:'C#',boxId:'83'},
{time:'9:00',name:'张14',sapId:'0018',direct:'C#',boxId:'84'},
{time:'9:20',name:'张15',sapId:'0019',direct:'C#',boxId:'85'},
{time:'9:40',name:'张16',sapId:'0020',direct:'C#',boxId:'86'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王11',sapId:'0021',direct:'Java',boxId:'87'},
{time:'10:20',name:'王12',sapId:'0022',direct:'Java',boxId:'88'},
{time:'11:00',name:'王13',sapId:'0023',direct:'Java',boxId:'89'},
{time:'11:20',name:'王14',sapId:'0024',direct:'Java',boxId:'90'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘11',sapId:'0025',direct:'前端',boxId:'91'},
{time:'14:20',name:'刘12',sapId:'0026',direct:'前端',boxId:'92'},
{time:'14:40',name:'刘13',sapId:'0027',direct:'前端',boxId:'93'},
{time:'15:00',name:'刘14',sapId:'0028',direct:'前端',boxId:'94'},
{time:'15:20',name:'刘15',sapId:'0029',direct:'前端',boxId:'95'},
{time:'15:40',name:'刘16',sapId:'0030',direct:'前端',boxId:'96'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周11',sapId:'0031',direct:'Java',boxId:'97'},
{time:'16:20',name:'',sapId:'',direct:'Java',boxId:'98'},
{time:'16:40',name:'周13',sapId:'0033',direct:'Java',boxId:'99'},
{time:'17:00',name:'周14',sapId:'0034',direct:'Java',boxId:'100'}
]},
]},
{week:'星期二',date:'11月5日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张1111',sapId:'0055',direct:'C#',boxId:'101'},
{time:'8:00',name:'张1112',sapId:'0056',direct:'C#',boxId:'102'},
{time:'8:40',name:'张1113',sapId:'0057',direct:'C#',boxId:'103'},
{time:'9:00',name:'张1114',sapId:'0058',direct:'C#',boxId:'104'},
{time:'9:20',name:'张1115',sapId:'0059',direct:'C#',boxId:'105'},
{time:'9:40',name:'张1116',sapId:'0060',direct:'C#',boxId:'106'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王1111',sapId:'0061',direct:'Java',boxId:'107'},
{time:'10:20',name:'王1112',sapId:'0062',direct:'Java',boxId:'108'},
{time:'11:00',name:'王1113',sapId:'0063',direct:'Java',boxId:'109'},
{time:'11:20',name:'王1114',sapId:'0064',direct:'Java',boxId:'110'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘1111',sapId:'0065',direct:'前端',boxId:'111'},
{time:'14:20',name:'刘1112',sapId:'0066',direct:'前端',boxId:'112'},
{time:'14:40',name:'刘1113',sapId:'0067',direct:'前端',boxId:'113'},
{time:'15:00',name:'刘1114',sapId:'0068',direct:'前端',boxId:'114'},
{time:'15:20',name:'刘1115',sapId:'0069',direct:'前端',boxId:'115'},
{time:'15:40',name:'刘1116',sapId:'0070',direct:'前端',boxId:'116'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周1111',sapId:'0071',direct:'Java',boxId:'117'},
{time:'16:20',name:'周1112',sapId:'0072',direct:'Java',boxId:'118'},
{time:'16:40',name:'周1113',sapId:'0073',direct:'Java',boxId:'119'},
{time:'17:00',name:'周1114',sapId:'0074',direct:'Java',boxId:'120'}
]},
]},
{week:'星期四',date:'11月7日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张11111',sapId:'0095',direct:'C#',boxId:'121'},
{time:'8:00',name:'张11112',sapId:'0096',direct:'C#',boxId:'122'},
{time:'8:40',name:'张11113',sapId:'0097',direct:'C#',boxId:'123'},
{time:'9:00',name:'张11114',sapId:'0098',direct:'C#',boxId:'124'},
{time:'9:20',name:'张11115',sapId:'0099',direct:'C#',boxId:'125'},
{time:'9:40',name:'张11116',sapId:'00100',direct:'C#',boxId:'126'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王11111',sapId:'00101',direct:'Java',boxId:'127'},
{time:'10:20',name:'王11112',sapId:'00102',direct:'Java',boxId:'128'},
{time:'11:00',name:'王11113',sapId:'00103',direct:'Java',boxId:'129'},
{time:'11:20',name:'王11114',sapId:'00104',direct:'Java',boxId:'130'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘11111',sapId:'00105',direct:'前端',boxId:'131'},
{time:'14:20',name:'刘11112',sapId:'00106',direct:'前端',boxId:'132'},
{time:'14:40',name:'刘11113',sapId:'00107',direct:'前端',boxId:'133'},
{time:'15:00',name:'刘11114',sapId:'00108',direct:'前端',boxId:'134'},
{time:'15:20',name:'刘11115',sapId:'00109',direct:'前端',boxId:'135'},
{time:'15:40',name:'刘11116',sapId:'00200',direct:'前端',boxId:'136'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周11111',sapId:'00201',direct:'Java',boxId:'137'},
{time:'16:20',name:'周11112',sapId:'00202',direct:'Java',boxId:'138'},
{time:'16:40',name:'周11113',sapId:'00203',direct:'Java',boxId:'139'},
{time:'17:00',name:'周11114',sapId:'00204',direct:'Java',boxId:'140'}
]},
]},
{week:'星期五',date:'11月8日',etc:[
{direct:'C#',detail:[
{time:'8:00',name:'张111111',sapId:'00225',direct:'C#',boxId:'141'},
{time:'8:00',name:'张111112',sapId:'00226',direct:'C#',boxId:'142'},
{time:'8:40',name:'张111113',sapId:'00227',direct:'C#',boxId:'143'},
{time:'9:00',name:'张111114',sapId:'00228',direct:'C#',boxId:'144'},
{time:'9:20',name:'张111115',sapId:'00229',direct:'C#',boxId:'145'},
{time:'9:40',name:'张111116',sapId:'00230',direct:'C#',boxId:'146'}
]},
{direct:'Java',detail:[
{time:'10:00',name:'王111111',sapId:'00231',direct:'Java',boxId:'147'},
{time:'10:20',name:'王111112',sapId:'00232',direct:'Java',boxId:'148'},
{time:'11:00',name:'王111113',sapId:'00233',direct:'Java',boxId:'149'},
{time:'11:20',name:'王111114',sapId:'00234',direct:'Java',boxId:'150'}
]},
{direct:'前端',detail:[
{time:'13:40',name:'刘111111',sapId:'00235',direct:'前端',boxId:'151'},
{time:'14:20',name:'刘111112',sapId:'00236',direct:'前端',boxId:'152'},
{time:'14:40',name:'刘111113',sapId:'00237',direct:'前端',boxId:'153'},
{time:'15:00',name:'刘111114',sapId:'00238',direct:'前端',boxId:'154'},
{time:'15:20',name:'刘111115',sapId:'00239',direct:'前端',boxId:'155'},
{time:'15:40',name:'刘111116',sapId:'00240',direct:'前端',boxId:'156'}
]},
{direct:'Java',detail:[
{time:'16:00',name:'周111111',sapId:'00241',direct:'Java',boxId:'157'},
{time:'16:20',name:'周111112',sapId:'00242',direct:'Java',boxId:'158'},
{time:'16:40',name:'周111113',sapId:'00243',direct:'Java',boxId:'159'},
{time:'17:00',name:'周111114',sapId:'00244',direct:'Java',boxId:'160'}
]}
]}
]}
]
constructor() { } ngOnInit() {
}
moveStart(directname){
this.dragCurrentDirect = directname;
}
moveEnd(directname){
this.dragCurrentDirect = '';
}
handleMove(fromData,toData){
let oldItem = JSON.parse(JSON.stringify(fromData.data));
let newItem = JSON.parse(JSON.stringify(toData));
console.log(fromData,toData);
this.menuContent.forEach(item0=>{
item0.dateArr.forEach(item1=>{
item1.etc.forEach(item2=>{
item2.detail.forEach(item3=>{
if(oldItem.boxId == item3.boxId){
item3.sapId = newItem.sapId;
item3.name = newItem.name;
}
if(newItem.boxId == item3.boxId){
item3.sapId = oldItem.sapId;
item3.name = oldItem.name;
}
})
})
})
})
}
}

angular实现draggable拖拽的更多相关文章

  1. angular ng-repeat+sortable 拖拽demo

    由于项目需求,需要使用angular 实现列表的增.删.改,并且列表支持拖拽. 看了下angular-ui 里面的sortable组件,使用起来也是非常简单,几十行代码就完成了所需功能. 我现在懒得想 ...

  2. draggable()拖拽时限制移动区域

    jQuery-UI为我们提供了一个非常便捷的拖拽方法:draggable(),在使用此方法时,我们可能会希望控件只在某一区域中移动,不能被拖出边界,这样的话我们可以使用下面的方法: 调用draggab ...

  3. jquery-ui.min.js的draggable()拖拽功能

    <!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  4. Angular 学习笔记——拖拽

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  5. Vue.Draggable拖拽效果

    1.下载包:npm install vuedraggable 配置:package.json "dependencies": { "vuedraggable": ...

  6. 使用angular帮你实现拖拽

    拖拽有多种写法,在这里就看一看angular版的拖拽. <!DOCTYPE html> <html ng-app="myApp"> <head> ...

  7. jquery UI 跟随学习笔记——拖拽(Draggable)

    引言 这周暂时没有任务下达,所以老大给我的任务就是熟悉jquery相关插件,我就先选择了jquery UI插件,以及jquery库学习. 我用了两天的时候熟悉Interactions模块中的Dragg ...

  8. Flutter 拖拽控件Draggable

    Flutter提供了强大的拖拽控件,可以灵活定制,并且非常简单.下面作一个拖拽的案例. Draggable Widget Draggable控件负责就是拖拽,父层使用了Draggable,它的子元素就 ...

  9. 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽

    前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...

随机推荐

  1. Java虚拟机的内存

    JDK1.8之前,java内存分为 线程共享区:堆.方法区.直接内存(非运行时数据区的一部分).线程私有区:程序计数器.虚拟机栈.本地方法栈. JDK1.8开始,虚拟机取消了方法区,改为元空间. 程序 ...

  2. JVM集训-----内存结构

    一.程序计数器/PC寄存器 (Program Counter Registe) 用于保存当前正在执行的程序的内存地址(下一条jvm指令的执行地址),由于Java是支持多线程执行的,所以程序执行的轨迹不 ...

  3. vue cli3.0 封装组件全局引入js文件并发布到npm

    首先用 vue create创建一个项目 当前的项目目录是这样的: 首先需要创建一个 packages 目录,用来存放组件 然后将 src 目录改为 examples 用作示例 二.修改配置 启动项目 ...

  4. cglib测试例子和源码详解

    目录 简介 为什么会有动态代理? 常见的动态代理有哪些? 什么是cglib 使用例子 需求 工程环境 主要步骤 创建项目 引入依赖 编写被代理类 编写MethodInterceptor接口实现类 编写 ...

  5. 【集训Day1 测试】装饰

    装饰(decorate) [题目描述] 一个图有 N 个结点,编号 1 至 N,有 M 条无向边,第 i 条边连接的两个结点是 Ai 和Bi,其中 Ai 和 Bi 是不同的结点.可能有多条边连接的是同 ...

  6. 对 /langversion 无效;必须是 ISO-1、ISO-2、3、4、5 或 Default

    反编译或者.net用更高版本打开时会出现这个问题,解决办法如下: 1.网页版程序,将解决方案中的Web.config中的 /langversion 的值改为指定的值,既可以解决,我这里采用的是默认值, ...

  7. python calendar 时间处理类库

    #python中的calendar import calendar #返回指定年的某月 def get_month(year, month): return calendar.month(year, ...

  8. 上传一个项目到GitHub

    在github上创建hello的仓库 上传本地项目文件 echo "# hello" >> README.md git init git add README.md g ...

  9. javascript实用Date工具

    时间字符串和年月日数据之间的自由转换工具:2018年更新版 上代码: /** * @Desc: 时间处理工具 * @Author: 拿饭盒当烟灰缸 * @Date: 2018-02-27 15:42: ...

  10. 白话OAuth2用户认证及鉴权标准流程

    一.OAuth2需求场景 在说明OAuth2需求及使用场景之前,需要先介绍一下OAuth2授权流程中的各种角色: 资源拥有者(User) - 指应用的用户 认证服务器 (Authorization S ...