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

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

参考文章: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. ZeroC ICE的远程调用框架 Callback(一)-AMI异步方法调用框架

    Ice框架提供了不少回调设施,其中一些是使用Ice远程调用进行ami模式或amd模式的支撑.本篇来看一下用于代理端的回调设施. Ice代码中有好几个Callback相关命名的基类,并且slice还会为 ...

  2. hopper逆向的伪代码令人大跌眼镜

    网上介绍hopper有逆向伪代码的文章很多,并以为其是万能而且cool B的.但是并没有人去求证hopper的逆向伪代码参考系数(参考价值,大家做过开发都清楚明白,有些功能看起来很花很cool但不实用 ...

  3. Linux下的磁盘分区,和创建文件系统(理论及实战)

    首先我们先了解一下磁盘的原理 磁盘的数据结构有: 扇区:盘片被分为多个扇形区域,每一个扇区存放512个字节的数据 磁道:同一个盘片不同半径的同心圆 柱面:不同盘片相同半径构成的圆柱面 公式: 磁盘存储 ...

  4. 2019-10-2,html作业,简历源码

    <html> <head> <title>简历作业</title> </head> <body bgcolor=#cccccc> ...

  5. 内网环境搭建NTP服务器

    说在前面:ntp和ntpdate区别 ①两个服务都是centos自带的(centos7中不自带ntp).ntp的安装包名是ntp:ntpdate的安装包是ntpdate.他们并非由一个安装包提供. ② ...

  6. k8s 上使用 StatefulSet 部署 zookeeper 集群

    目录 StatefulSet 部署 zookeeper 集群 创建pv StatefulSet 测试 StatefulSet 部署 zookeeper 集群 参考 k8s官网zookeeper集群的部 ...

  7. Docker 遇到的一些错误

    1.version Base not defined in file libdevmapper.so.1.02 在 Centos 6.5 上安装docker-io之后,使用/etc/init.d/do ...

  8. PHP后端代码生成微信小程序带参数的二维码保存成jpg图片上传到服务器getwxacodeunlimit

    老板最近有点飘了,他要在PC端的网站放一个微信小程序的二维码,并且扫描这个二维码以后要跳到小程序对应的房源详情页. 这是微信官方给出的文档,连接地址:https://developers.weixin ...

  9. c# 窗体开发2 高级控件的使用

    1.单选按钮(RadioButton) 同一组中其他单选按钮不能同时选定 分组形式:panel GoupBox 窗体 方法: 属性 说明 Appearance RadioButton 控件的显示与命令 ...

  10. PHP经典面试题目汇总

    1.双引号和单引号的区别 双引号解释变量,单引号不解释变量 双引号里插入单引号,其中单引号里如果有变量的话,变量解释 双引号的变量名后面必须要有一个非数字.字母.下划线的特殊字符,或者用{}讲变量括起 ...