angular实现draggable拖拽
前言:最近项目要实现一个拖拽功能,我在网上开始了各类搜寻,虽然后面因为数据原因舍弃了拖拽的这一需求,但是为了不辜负最近的研究,还是来记录一下。
场景需求:面试预约选时间节点,候选人之间是可以相互交换的,但是局限于面试方向相同的候选人才能相互拖拽(拖拽后即表示两个候选人之间交换面试时间)。本来此种场景上图更为明确,奈何公司只限于内网开发,上传不了图片,嘤嘤嘤。。。
参考文章: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拖拽的更多相关文章
- angular ng-repeat+sortable 拖拽demo
由于项目需求,需要使用angular 实现列表的增.删.改,并且列表支持拖拽. 看了下angular-ui 里面的sortable组件,使用起来也是非常简单,几十行代码就完成了所需功能. 我现在懒得想 ...
- draggable()拖拽时限制移动区域
jQuery-UI为我们提供了一个非常便捷的拖拽方法:draggable(),在使用此方法时,我们可能会希望控件只在某一区域中移动,不能被拖出边界,这样的话我们可以使用下面的方法: 调用draggab ...
- jquery-ui.min.js的draggable()拖拽功能
<!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- Angular 学习笔记——拖拽
<!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...
- Vue.Draggable拖拽效果
1.下载包:npm install vuedraggable 配置:package.json "dependencies": { "vuedraggable": ...
- 使用angular帮你实现拖拽
拖拽有多种写法,在这里就看一看angular版的拖拽. <!DOCTYPE html> <html ng-app="myApp"> <head> ...
- jquery UI 跟随学习笔记——拖拽(Draggable)
引言 这周暂时没有任务下达,所以老大给我的任务就是熟悉jquery相关插件,我就先选择了jquery UI插件,以及jquery库学习. 我用了两天的时候熟悉Interactions模块中的Dragg ...
- Flutter 拖拽控件Draggable
Flutter提供了强大的拖拽控件,可以灵活定制,并且非常简单.下面作一个拖拽的案例. Draggable Widget Draggable控件负责就是拖拽,父层使用了Draggable,它的子元素就 ...
- 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽
前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...
随机推荐
- ZeroC ICE的远程调用框架 Callback(一)-AMI异步方法调用框架
Ice框架提供了不少回调设施,其中一些是使用Ice远程调用进行ami模式或amd模式的支撑.本篇来看一下用于代理端的回调设施. Ice代码中有好几个Callback相关命名的基类,并且slice还会为 ...
- hopper逆向的伪代码令人大跌眼镜
网上介绍hopper有逆向伪代码的文章很多,并以为其是万能而且cool B的.但是并没有人去求证hopper的逆向伪代码参考系数(参考价值,大家做过开发都清楚明白,有些功能看起来很花很cool但不实用 ...
- Linux下的磁盘分区,和创建文件系统(理论及实战)
首先我们先了解一下磁盘的原理 磁盘的数据结构有: 扇区:盘片被分为多个扇形区域,每一个扇区存放512个字节的数据 磁道:同一个盘片不同半径的同心圆 柱面:不同盘片相同半径构成的圆柱面 公式: 磁盘存储 ...
- 2019-10-2,html作业,简历源码
<html> <head> <title>简历作业</title> </head> <body bgcolor=#cccccc> ...
- 内网环境搭建NTP服务器
说在前面:ntp和ntpdate区别 ①两个服务都是centos自带的(centos7中不自带ntp).ntp的安装包名是ntp:ntpdate的安装包是ntpdate.他们并非由一个安装包提供. ② ...
- k8s 上使用 StatefulSet 部署 zookeeper 集群
目录 StatefulSet 部署 zookeeper 集群 创建pv StatefulSet 测试 StatefulSet 部署 zookeeper 集群 参考 k8s官网zookeeper集群的部 ...
- Docker 遇到的一些错误
1.version Base not defined in file libdevmapper.so.1.02 在 Centos 6.5 上安装docker-io之后,使用/etc/init.d/do ...
- PHP后端代码生成微信小程序带参数的二维码保存成jpg图片上传到服务器getwxacodeunlimit
老板最近有点飘了,他要在PC端的网站放一个微信小程序的二维码,并且扫描这个二维码以后要跳到小程序对应的房源详情页. 这是微信官方给出的文档,连接地址:https://developers.weixin ...
- c# 窗体开发2 高级控件的使用
1.单选按钮(RadioButton) 同一组中其他单选按钮不能同时选定 分组形式:panel GoupBox 窗体 方法: 属性 说明 Appearance RadioButton 控件的显示与命令 ...
- PHP经典面试题目汇总
1.双引号和单引号的区别 双引号解释变量,单引号不解释变量 双引号里插入单引号,其中单引号里如果有变量的话,变量解释 双引号的变量名后面必须要有一个非数字.字母.下划线的特殊字符,或者用{}讲变量括起 ...