Ant Design的可编辑Tree的实现操作


Posted in Javascript onOctober 31, 2020

前言

最近在用Ant Design写一个后台,遇到的需求就是实现一个可动态增减和编辑子节点的Tree。GitHub上看了一圈,没好用和合适的。索性就基于Ant Design中的Tree组件写一个。

实现的效果如下:

可以增加子节点

可以删除子节点

可以编辑子节点信息

可以取消编辑信息

具体的效果图如下:

Ant Design的可编辑Tree的实现操作

主要的就是借助 TreeNode 的 title 属性,它的类型是string|ReactNode。

正文

经过分析,一个节点的数据结构应该是

{
  value: 'Root', // 显示的信息
  defaultValue: 'Root', // 当某一节点进入编辑状态,然后点击close按钮,节点的信息应该恢复原始状态,
  key: '0-1', // 节点的Key,全局唯一
  parentKey: '0', // 父节点的Key
  isEditable: false // 是否处于可编辑状态
  children:[] // 子节点
}

通过数据结构组装TreeNode的代码如下:

data= [
   {
    value: 'Root',
    defaultValue: 'Root',
    key: '0-1',
    parentKey: '0',
    isEditable: false
   }
  ];
  
  state={
    data: this.data
  }
 
renderTreeNodes = data => data.map((item) => {
  if (item.isEditable) { // 编辑状态下
   item.title = (
    <div>
     <input value={item.value}
      onChange={(e) => this.onChange(e, item.key)}/>
     <Icon type='close' style={{marginLeft:10}} onClick={() => this.onClose(item.key, item.defaultValue)}/>
     <Icon type='check' style={{marginLeft:10}} onClick={() => this.onSave(item.key)}/>
    </div>
   );
  } else {
   item.title = (
    <div>
     <span>
      {item.value}
     </span>
     <Icon style={{ marginLeft: 10 }} type='edit' onClick={() => this.onEdit(item.key)} />
     <Icon style={{ marginLeft: 10 }} type='plus' onClick={() => this.onAdd(item.key)} />
     {item.parentKey === '0' ? null : (<Icon style={{ marginLeft: 10 }} type='minus' onClick={() => this.onDelete(item.key)} />)} // 根节点没有删除按钮
    </div>
   )
  }
 
  if (item.children) {
   return (
    <TreeNode title={item.title} key={item.key} dataRef={item}>
     {this.renderTreeNodes(item.children)}
    </TreeNode>
   );
  }
 
  return <TreeNode {...item}/>;
 })
 
 ...
 // 渲染界面
 render() {
  return (
   <div>
    <Tree>
     {this.renderTreeNodes(this.state.data)}
    </Tree>
   </div>
  )
 }

之后所有的增删修改等都是先修改data这个数组中的数据,然后使用this.setState({ data: this.data })更新界面,具体的看下代码就成,很简单。

最后优化这个组件的时候,遇到一个比较坑的。本来想是当在某节点上增加子节点时,父节点自动展开,代码逻辑上没有问题,但是必须手动执行过一次展开或者搜索的操作,所写的逻辑才能生效。

后来没办法,只能在生命周期函数中DOM加载完毕后主动触发下:

componentDidMount() {
  this.onExpand([]); // 手动触发,否则会遇到第一次添加子节点不展开的Bug
 }

代码放在GitHub上了,地址是 react-editable-tree,欢迎有同样需要的小伙伴参考,star和fork 也是极好的。

补充知识:关于antd Select 限制选择个数的解决方案

应用场景描述:

Select 被form 所包裹,且被getFieldDecorator修饰。所以值的改变应该通过form的setFieldsValue方法。

Select模式肯定会是multiple。且以最多三个值举例。

解决思路如下:

1 起初是想在Select的onchange事件中判断values的数量,数量大于三个的时候来重新setFieldsValue;且把最后的选项值替换成刚刚选择的值。

后来发现setFieldsValue方法不起作用,Select的值会一直增加。后来想想可能是 setFieldsValue与onchange 冲突,通过setFieldsValue 无法改变onchange后的值。

2 最后通过重新查看文档。发现还有一个方法可用,即 validator。验证值,通过验证所选值的数量是否大于三个,然后重新setFieldsValue ;发现此法可行。从而解决该疑难杂症。

好,最后附上代码供参考:

changeValues = (rule ,value , callback)=> {
const { setFieldsValue } = this.props.form ;

let newArr ;

if (value.length > 3){


newArr = [].concat(value.slice(0,2), value.slice(-1) ) ;


setFieldsValue({


"languages" : newArr ,


})


callback('最多选择三种语言')

} else {


newArr = value ;


callback()

}
}
 
<FormItem>
{getFieldDecorator('languages', {
rules:[{required: true,message : '请选择三种语言',
validator : changeValues
}],
validateTrigger : 'onChange',
})(
<Select mode='multiple' >
 

<Option key={1} value={1}>1</Option>

<Option key={2} value={2}>2</Option>
 
<Option key={3} value={3}>3</Option>

<Option key={4} value={4}>4</Option>

<Option key={5} value={5}>5</Option>
</Select>
)}
</FormItem>

以上这篇Ant Design的可编辑Tree的实现操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS BASE64编码 window.atob(), window.btoa()
Mar 09 Javascript
JavaScript 新手24条实用建议[TUTS+]
Jun 21 Javascript
Jquery优化效率 提升性能解决方案
Sep 06 Javascript
js控制表单奇偶行样式的简单方法
Jul 31 Javascript
使用jquery.qrcode生成彩色二维码实例
Aug 08 Javascript
jquery比较简洁的软键盘特效实现方法
Mar 19 Javascript
AngularJS 实现弹性盒子布局的方法
Aug 30 Javascript
深入理解Node.js的HTTP模块
Oct 12 Javascript
详解Js模板引擎(TrimPath)
Nov 22 Javascript
使用BootStrap进行轮播图的制作
Jan 06 Javascript
Vue用v-for给循环标签自身属性添加属性值的方法
Oct 18 Javascript
vue使用el-upload上传文件及Feign服务间传递文件的方法
Mar 15 Javascript
antd多选下拉框一行展示的实现方式
Oct 31 #Javascript
解决antd 下拉框 input [defaultValue] 的值的问题
Oct 31 #Javascript
Vue使用CDN引用项目组件,减少项目体积的步骤
Oct 30 #Javascript
vue+swiper实现左右滑动的测试题功能
Oct 30 #Javascript
利用vue3+ts实现管理后台(增删改查)
Oct 30 #Javascript
vue项目页面嵌入代码块vue-prism-editor的实现
Oct 30 #Javascript
解决vue侦听器watch,调用this时出现undefined的问题
Oct 30 #Javascript
You might like
PHP对MongoDB[NoSQL]数据库的操作
2013/03/01 PHP
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
2013/06/14 PHP
PHP的魔术常量__METHOD__简介
2014/07/08 PHP
PHP中的闭包(匿名函数)浅析
2015/02/07 PHP
php实现多维数组中每个单元值(数字)翻倍的方法
2015/02/16 PHP
CI框架常用函数封装实例
2016/11/21 PHP
jQuery结合PHP+MySQL实现二级联动下拉列表[实例]
2011/11/15 Javascript
网页右下角弹出窗体实现代码
2014/06/05 Javascript
jQuery大于号(&gt;)选择器的作用解释
2015/01/13 Javascript
JavaScript制作windows经典扫雷小游戏
2015/03/31 Javascript
javascript中动态函数用法实例分析
2015/05/14 Javascript
win7下安装配置node.js+express开发环境
2015/12/06 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
2016/02/14 Javascript
JS传递对象数组为参数给后端,后端获取的实例代码
2016/06/28 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
2016/11/18 Javascript
JS实现动态修改table及合并单元格的方法示例
2017/02/20 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
JS实现的简单表单验证功能示例
2017/10/13 Javascript
vue.js动画中的js钩子函数的实现
2018/07/06 Javascript
Bootstrap导航菜单点击后无法自动添加active的处理方法
2018/08/10 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
vue轮播组件实现$children和$parent 附带好用的gif录制工具
2019/09/26 Javascript
Vue实现购物车基本功能
2020/11/08 Javascript
JavaScript 声明私有变量的两种方式
2021/02/05 Javascript
[04:40]DOTA2-DPC中国联赛1月26日Recap集锦
2021/03/11 DOTA
Python编写Windows Service服务程序
2018/01/04 Python
python实现一行输入多个值和一行输出多个值的例子
2019/07/16 Python
python 画3维轨迹图并进行比较的实例
2019/12/06 Python
python-docx文件定位读取过程(尝试替换)
2020/02/13 Python
使用Python将语音转换为文本的方法
2020/08/10 Python
AmazeUI 手机版页面的顶部导航条Header与侧边导航栏offCanvas的示例代码
2020/08/19 HTML / CSS
什么是唯一索引
2015/07/05 面试题
党校个人自我鉴定范文
2014/03/28 职场文书
代领学位证书毕业证书委托书
2014/09/30 职场文书
2014年幼儿园园务工作总结
2014/12/05 职场文书
Rust中的Struct使用示例详解
2022/08/14 Javascript