IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> ng-zorro中树(nz-tree)的拖拽 -> 正文阅读

[JavaScript知识库]ng-zorro中树(nz-tree)的拖拽

zorro的11版本
angular11版本

使用场景:
把已经组织好的菜单设置为可以拖拽排序。使用tree来完成这个功能

方法思路:
1、选择正确的组件示例与方法
2、对拖拽前行为进行判断,不合法的拖拽进行阻止
3、对获取的数据进行处理,方便传给后端
先分步实现,下面有完整代码

1、选择正确的组件示例与方法

使用这两个tree示例(结合使用)
在这里插入图片描述

在这里插入图片描述

提示:第一个示例,无论调不调接口,都能完成视觉上的拖拽,并获得拖拽前后的数据。第二个示例,拖拽前校验,不符合条件的,阻止拖拽。这里两个合用是的效果就是:满足条件就有拖拽效果,不满足条件,无法拖拽(不调用接口排序时)

怎么感觉不使用第二个也行呢,嗯!!!!!!!!

当我不使用拖拽前校验(第二个)时,对拖拽前判断时,不好判断,还是使用吧
代码:

 <nz-tree [nzData]="nodesTree" nzDraggable nzBlockNode 
		 (nzOnDrop)="nzEventTree($event)" 
		 [nzBeforeDrop]="beforeDrop"> 
 </nz-tree>

2、对拖拽前行为进行判断,不合法的拖拽进行阻止

// 子等级与父等级级别不可以改变。只可以改变菜单的排列顺序与位置
// 简单来说就是,父级不能拖拽到其他父级的子级里。子级不能拖到外面成为父级。子级可以在不同的父级下拖拽排序。
// 这里有个特殊的就是:把子级拖拽到父级children=0下,这里不好判断,我写在了第三个if里,看客吗有好的判断方法的话,告诉我一下,感激不尽
nzEventTree(event: NzFormatEmitEvent | any): void | any {
	// this.cdr.markForCheck();
	console.log(event);
	if (event.node.level === 0 && event.dragNode.level === 0) {
	 return this.message.error('父级间移动');
	} else if (event.node.level === 1 && event.dragNode.level === 1) {
	  return this.message.error('子级间移动');
	} else if ( event.node.origin.children.length === 1 && event.dragNode.level === 1 && event.node.level === 0 ) {
	return this.message.error('将子级向空的目录下移动');
	} else {
	  return this.message.error('不可移动');
	}
}-+



beforeDrop(arg: NzFormatBeforeDropEvent): any {
    // 要判断是子级移动还是父级移动
    if (arg.node.level === 0 && arg.dragNode.level === 0 && arg.pos !== 0) {
      return of(true);
    } else if (arg.node.level === 1 && arg.dragNode.level === 1) {
      return of(true);
    } else if (arg.node.level === 0 && arg.dragNode.level === 1 && arg.pos === 0) {
      return of(true);
    } else {
      return of(false);
    }
  }

两个函数代码中的判断看似一样,但解释已经放在代码里了

3、对获取的数据进行处理,方便传给后端

数据处理结果:
[
{
父级id:,
子级id:,
排序:,
}
]

const afterArr: any = [];
    if (event.node.level === 0 && event.dragNode.level === 0) {
      // 父级移动
      console.log(event.dragNode.service.rootNodes);
      let arr: any = [];
      arr = event.dragNode.service.rootNodes;
      arr.forEach((element: any, i: number) => {
        const obj: any = {};
        obj.id = element.key;
        obj.parentId = 0;
        obj.sort = i + 2;
        afterArr.push(obj);
      });
      console.log(afterArr);
    } else if (event.node.level === 1 && event.dragNode.level === 1) {
      let parentIdAfter = event.node.origin.parentId;
      // 子级移动
      if (event.node.origin.parentId === event.dragNode.origin.parentId) {
        const arr: any = event.dragNode.parentNode.origin;
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      } else {
        // 这里判断跨域后的父级有没有子级,parentNode为不为空
        let arr: any;
        if (event.node.parentNode === null) {
          arr = event.node.origin;
          parentIdAfter = event.node.key;
        } else {
          arr = event.node.parentNode.origin;
        }
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      }
    } else if ( event.node.origin.children.length === 1 && event.dragNode.level === 1 && event.node.level === 0) {
      // 当拖拽的目标对象为空时走这个路
      let parentIdAfter = event.node.origin.parentId;
      // 子级移动
      if (event.node.origin.parentId === event.dragNode.origin.parentId) {
        const arr: any = event.dragNode.parentNode.origin;
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      } else {
        // 这里判断跨域后的父级有没有子级,parentNode为不为空
        let arr: any;
        if (event.node.parentNode === null) {
          arr = event.node.origin;
          parentIdAfter = event.node.key;
        } else {
          arr = event.node.parentNode.origin;
        }
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      }
    } else {
      return this.message.error('不可非法移动');
    }
    // 调用拖拽的接口
    let list: any = [];
    list = afterArr;
    this.organizationService.menutpProsystem({ list }).then((res: any) => {
      if (res.code === 200) {
        this.message.success('移动成功');
      } else {
        this.message.success('不可非法移动');
      }
    }).catch();

4、完整代码

 <nz-alert nzType="info" nzMessage="特别提示:移动时,蓝色线的长短代表级别"></nz-alert>
      <br />
      <nz-alert nzType="info" nzMessage="提示:子等级与父等级级别不可以改变。只可以改变菜单的排列顺序与位置"></nz-alert>
        <nz-tree [nzData]="nodesTree" nzDraggable nzBlockNode (nzOnDrop)="nzEventTree($event)" [nzBeforeDrop]="beforeDrop"> </nz-tree>
      <br />
  nzEventTree(event: NzFormatEmitEvent | any): void | any {
    this.cdr.markForCheck();
    const afterArr: any = [];
    if (event.node.level === 0 && event.dragNode.level === 0) {
      // 父级移动
      console.log(event.dragNode.service.rootNodes);
      let arr: any = [];
      arr = event.dragNode.service.rootNodes;
      arr.forEach((element: any, i: number) => {
        const obj: any = {};
        obj.id = element.key;
        obj.parentId = 0;
        obj.sort = i + 2;
        afterArr.push(obj);
      });
      console.log(afterArr);
    } else if (event.node.level === 1 && event.dragNode.level === 1) {
      let parentIdAfter = event.node.origin.parentId;
      // 子级移动
      if (event.node.origin.parentId === event.dragNode.origin.parentId) {
        const arr: any = event.dragNode.parentNode.origin;
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      } else {
        // 这里判断跨域后的父级有没有子级,parentNode为不为空
        let arr: any;
        if (event.node.parentNode === null) {
          arr = event.node.origin;
          parentIdAfter = event.node.key;
        } else {
          arr = event.node.parentNode.origin;
        }
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      }
    } else if ( event.node.origin.children.length === 1 && event.dragNode.level === 1 && event.node.level === 0) {
      // 当拖拽的目标对象为空时走这个路
      let parentIdAfter = event.node.origin.parentId;
      // 子级移动
      if (event.node.origin.parentId === event.dragNode.origin.parentId) {
        const arr: any = event.dragNode.parentNode.origin;
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      } else {
        // 这里判断跨域后的父级有没有子级,parentNode为不为空
        let arr: any;
        if (event.node.parentNode === null) {
          arr = event.node.origin;
          parentIdAfter = event.node.key;
        } else {
          arr = event.node.parentNode.origin;
        }
        arr.children.forEach((element: any, i: number) => {
          const obj: any = {};
          obj.id = element.key;
          obj.parentId = parentIdAfter;
          obj.sort = i;
          afterArr.push(obj);
        });
        this.cdr.markForCheck();
      }
    } else {
      return this.message.error('不可非法移动');
    }
    // 调用拖拽的接口
    let list: any = [];
    list = afterArr;
    this.organizationService.menutpProsystem({ list }).then((res: any) => {
      if (res.code === 200) {
        this.message.success('移动成功');
      } else {
        this.message.success('不可非法移动');
      }
    }).catch();
  }
  beforeDrop(arg: NzFormatBeforeDropEvent): any {
    // 要判断是子级移动还是父级移动
    if (arg.node.level === 0 && arg.dragNode.level === 0 && arg.pos !== 0) {
      return of(true);
    } else if (arg.node.level === 1 && arg.dragNode.level === 1) {
      return of(true);
    } else if (arg.node.level === 0 && arg.dragNode.level === 1 && arg.pos === 0) {
      return of(true);
    } else {
      return of(false);
    }
  }
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 15:40:27  更:2021-12-23 15:43:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:42:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码