学无先后,达者为师

网站首页 编程语言 正文

ng-zorro中树(nz-tree)的拖拽

作者:蒲公英 更新时间: 2022-01-09 编程语言

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);
    }
  }

原文链接:https://blog.csdn.net/weixin_45158253/article/details/122094371

栏目分类
最近更新