ng-zorro11的modal组件可拖拽(模板创建的弹窗)

最近在项目中有需求可以拖拽的弹窗,网上搜索了一遍都是服务端创建的弹窗可拖拽,而通过template创建的弹窗确比较难实现,我参考了别人的实现,改造了一下,就可以实现template的拖拽。

1. 创建指令 drag-modal.directive.ts

import { Directive, ElementRef, Input } from @angular/core;
import { ModalDragService } from "./drag-modal.service";
import { NzModalRef } from ng-zorro-antd/modal;
@Directive({
  selector: [dragModal]
})
export class DragModalDirective {
  @Input() dragModal: NzModalRef;

  constructor(private ModalDragService: ModalDragService) { 
    setTimeout(() => {
      this.ModalDragService.dragServiceModal(this.dragModal);
    }, 16);
  }
}

2.创建指令服务drag-modal.service.ts

import { Injectable, RendererFactory2 } from @angular/core;
@Injectable({
  providedIn: root
})
export class ModalDragService {
  constructor( private rendererFactory2: RendererFactory2, ) { }

  dragTemplateModal(refModal) {
    const render = this.rendererFactory2.createRenderer(null, null);
    const modalBackground = refModal.getElement();
    const modalElement = refModal.getElement().querySelector(.ant-modal-content);
    const modalTitleElement = this.createModalTitleElement(render, modalElement);
    this.dragListen(render, modalTitleElement, modalElement, modalBackground);
  }

  dragServiceModal(refModal) {
    refModal.afterOpen.subscribe(() => {
      const render = this.rendererFactory2.createRenderer(null, null);
      const modalBackground = refModal.getElement();
      const modalElement = refModal.getElement().querySelector(.ant-modal-content);
      const modalTitleElement = this.createModalTitleElement(render, modalElement);
      this.dragListen(render, modalTitleElement, modalElement, modalBackground);
    })
  }

  createModalTitleElement(render, modalElement) {
    let element = document.createElement(div) as any;
    render.setStyle(element, width, 100%);
    render.setStyle(element, height, 54px);
    render.setStyle(element, position, absolute);
    render.setStyle(element, top, 0);
    render.setStyle(element, left, 0);
    render.setStyle(element, cursor, move);
    render.setStyle(element, -moz-user-select, none);
    render.setStyle(element, -webkit-user-select, none);
    render.setStyle(element, -ms-user-select, none);
    render.setStyle(element, -khtml-user-select, none);
    render.setStyle(element, user-select, none);
    render.appendChild(modalElement, element);
    return element;
  }
  dragListen(render, modalTitleElement, modalElement, modalBackground) {
    render.listen(modalTitleElement, mousedown, function (event) {
      this.mouseDownX = event.clientX;
      this.mouseDownY = event.clientY;
      this.modalX = modalElement.offsetLeft;
      this.modalY = modalElement.offsetTop;
      render.setStyle(modalElement, left, `${this.modalX}px`);
      render.setStyle(modalElement, top, `${this.modalY}px`);
      this.canMove = true;
    }.bind(this));
    render.listen(modalTitleElement, mouseup, function (event) {
      this.canMove = false;
    }.bind(this));
    render.listen(modalBackground, mousemove, function (event) {
      if (this.canMove) {
        let moveX = event.clientX - this.mouseDownX;
        let moveY = event.clientY - this.mouseDownY;
        let newModalX = this.modalX + moveX;
        let newModalY = this.modalY + moveY;
        render.setStyle(modalElement, left, `${newModalX}px`);
        render.setStyle(modalElement, top, `${newModalY}px`);
      }
    }.bind(this));
  }
}

3. 封装为一个moduledrag-modal.module.ts

import { NgModule } from @angular/core;
import { CommonModule } from @angular/common;
import { DragModalDirective } from "./drag-modal.directive";
import { ModalDragService } from "./drag-modal.service";

@NgModule({
  providers: [ModalDragService],
  declarations: [DragModalDirective],
  imports: [
    CommonModule,
  ],
  exports: [DragModalDirective]
})
export class ModalDragModule { }

然后把这个模块注入到根模块中,就可以愉快地拖拽了_

4.使用#dragModal [dragModal]="dragModal"

<nz-modal 
  #dragModal
  [dragModal]="dragModal">
 </nz-modal>
经验分享 程序员 微信小程序 职场和发展