老师,我的意思是,在本章的中间部分,在你加入service之前,我按照你的代码,演示后发现drop的时候,放到目标list无法显示背景色, 那个时候应该没有加入 dragEnterClass 吧。 另外,我将本章的所有代码都完成后,发现 handleMove 事件, 无法打印console.log,并且整个 task-list 也无法拖拽。我不知道是否和task-list有关,记得之前问过你关于task-list之间没有间隔的问题,不知道是不是之间有什么关联。但是我在task-list.component.ts 里面 oninit 时候打印是没有问题的。现在不知道该怎么处理了,请给一些意见,谢谢。
代码如下
在 drag 文件
import { Directive, HostListener, ElementRef, Renderer2, Input } from '@angular/core';
import {DragDropService} from '../drag-drop.service';
@Directive({
selector: '[app-draggable][draggedClass][dragTag][dragData]'
})
export class DragDirective {
private _isDraggable = false;
@Input('app-draggable')
set isDraggable(val: boolean) {
this._isDraggable = val;
this.rd.setAttribute(this.el.nativeElement, 'draggable', `${val}`);
}
get isDraggable() {
return this._isDraggable;
}
@Input() draggedClass: string;
// add service
@Input() dragTag: string;
@Input() dragData: any;
constructor(
private el: ElementRef,
private rd: Renderer2,
private service: DragDropService
) { }
@HostListener('dragstart', ['$event'])
onDragStart(ev: Event) {
if (this.el.nativeElement === ev.target) {
this.rd.addClass(this.el.nativeElement, this.draggedClass);
this.service.setDragData({tag: this.dragTag, data: this.dragData});
}
}
@HostListener('dragend', ['$event'])
ondragend(ev: Event) {
if (this.el.nativeElement === ev.target) {
this.rd.removeClass(this.el.nativeElement, this.draggedClass);
}
}
}
在 drop 文件
import { Directive, HostListener, ElementRef, Renderer2, Input, Output, EventEmitter } from '@angular/core';
import {DragDropService, DragData} from '../drag-drop.service';
@Directive({
selector: '[app-droppable][dragEnterClass][dropTags]'
})
export class DropDirective {
@Output() dropped = new EventEmitter<DragData>();
@Input() dragEnterClass: string;
@Input() dropTags: string[] = [];
private data$;
constructor(
private el: ElementRef,
private rd: Renderer2,
private service: DragDropService
) {
this.data$ = this.service.getDragData().take(1)
}
@HostListener('dragenter', ['$event'])
onDragEnter(ev: Event) {
ev.preventDefault();
ev.stopPropagation();
if (this.el.nativeElement === ev.target) {
this.data$.subscribe(dragData => {
if (this.dropTags.indexOf(dragData.tag) > -1) {
this.rd.addClass(this.el.nativeElement, this.dragEnterClass);
}
});
}
}
@HostListener('dragover', ['$event'])
onDragOver(ev: Event) {
ev.preventDefault();
ev.stopPropagation();
if (this.el.nativeElement === ev.target) {
this.data$.subscribe(dragData => {
if (this.dropTags.indexOf(dragData.tag) > -1) {
this.rd.setProperty(ev, 'dataTransfer.effectAllowed', 'all');
this.rd.setProperty(ev, 'dataTransfer.dropEffect', '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 (this.dropTags.indexOf(dragData.tag) > -1) {
this.rd.removeClass(this.el.nativeElement, this.dragEnterClass);
}
});
}
}
@HostListener('drop', ['$event'])
onDrop(ev: Event) {
ev.preventDefault();
ev.stopPropagation();
if(this.el.nativeElement === ev.target) {
this.data$.subscribe(dragData => {
if (this.dropTags.indexOf(dragData.tag) > -1) {
this.rd.removeClass(this.el.nativeElement, this.dragEnterClass);
this.dropped.emit(dragData);
this.service.clearDragData();
}
});
}
}
}
task-home 文件部分
<div class="task-lists">
<app-task-list
class="list-container"
app-droppable
[dropTags]="['task-item', 'task-list']"
[dragEnterClass]="'drag-enter'"
[app-draggable]="true"
[dragTag]="'task-list'"
[draggedClass]="'drag-start'"
[dragData]="list"
(dropped)="handleMove($event, list)"
*ngFor="let list of lists">
<app-task-header [header]="list.name"
(newTask)="openNewTaskDialog()"
(moveAll)="openCopyTaskDialog()"
(deleteList)="openConfirmDialog()"
(editList)="openEditListDialog()">
</app-task-header>
<app-task-item *ngFor="let task of list.tasks" [item]="task" (taskClick)="OpenUpdateTaskDialog(task)">
</app-task-item>
</app-task-list>
</div>
<button md-fab class="fab-button" type="button" (click)="openNewListDialog()">
<md-icon>add</md-icon>
</button>
在 task-item 部分
<md-list-item class="container"
[@item]="widerPriority"
[ngClass]="{
'priority-normal': item.priority === 3,
'priority-important': item.priority === 2,
'priority-emergency': item.priority === 1
}"
[app-draggable]="true"
[dragTag]="'task-item'"
[draggedClass]="'drag-start'"
[dragData]="item"
(click)="onItemClick()">
<md-checkbox class="completion-status" [checked]="item.completed" (click)="onCheckboxClick($event)"></md-checkbox>
<div md-line class="content" [ngClass]="{'completed': item.completed}">
<span [md-tooltip]="item.desc">{{item.desc}}</span>
</div>
<div md-line class="bottom-bar">
<span class="due-date" *ngIf="item.dueDate">
{{item.dueDate | date: "dd/MM/yy"}}
</span>
<md-icon *ngIf="item.remainder">alarm</md-icon>
</div>
<md-icon [svgIcon]="avatar" md-list-avatar class="avatar"></md-icon>
</md-list-item>
在task-home.component.ts 部分 代码
handleMove(srcData, list) {
switch(srcData.tag) {
case 'task-item':
console.log('handling item');
break;
case 'task-list':
console.log('handling list');
break;
default:
break;
}
}
万分感谢
全网首个介绍官方 Material 组件库用法与 Redux 在 Angular 中的应用
了解课程