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 相关文章推荐
用javascript来实现动画导航效果的代码
Dec 16 Javascript
js jquery验证银行卡号信息正则学习
Jan 21 Javascript
JS获取农历日期具体实例
Nov 14 Javascript
javascript动态创建链接的方法
May 13 Javascript
JS获取及验证开始结束日期的方法
Aug 20 Javascript
javascript checkbox/radio onchange不能兼容ie8处理办法
Jun 13 Javascript
详解win7 cmd执行vue不是内部命令的解决方法
Jul 27 Javascript
JavaScript面向对象精要(下部)
Sep 12 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
Dec 01 Javascript
node.js ws模块搭建websocket服务端的方法示例
Apr 25 Javascript
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 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新手上路(七)
2006/10/09 PHP
JavaScript词法作用域与调用对象深入理解
2012/11/29 Javascript
jquery struts 验证唯一标识(公用方法)
2013/03/27 Javascript
jquery easyui combox一些实用的小方法
2013/12/25 Javascript
js控制input框只读实现示例
2014/01/20 Javascript
js判断设备是否为PC并调整图片大小
2014/02/12 Javascript
JS实现div居中示例
2014/04/17 Javascript
JavaScript lastIndexOf方法入门实例(计算指定字符在字符串中最后一次出现的位置)
2014/10/17 Javascript
jQuery给元素添加样式的方法详解
2015/12/30 Javascript
给angular加上动画效遇到的问题总结
2016/02/17 Javascript
JQuery日期插件datepicker的使用方法
2016/03/03 Javascript
Javascript获取随机数的实现方法
2016/06/22 Javascript
js中scrollTop()方法和scroll()方法用法示例
2016/10/03 Javascript
js遍历json对象所有key及根据动态key获取值的方法(必看)
2017/03/09 Javascript
JS请求servlet功能示例
2017/06/01 Javascript
js禁止表单重复提交
2017/08/29 Javascript
JS+HTML5 Canvas实现简单的写字板功能示例
2018/08/30 Javascript
小程序登录/注册页面设计的实现代码
2019/05/24 Javascript
Vue触发隐藏input file的方法实例详解
2019/08/14 Javascript
ES6使用新特性Proxy实现的数据绑定功能实例
2020/05/11 Javascript
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
Python中常见的数据类型小结
2015/08/29 Python
django+mysql的使用示例
2018/11/23 Python
Pandas0.25来了千万别错过这10大好用的新功能
2019/08/07 Python
python 类的继承 实例方法.静态方法.类方法的代码解析
2019/08/23 Python
pytorch 图像中的数据预处理和批标准化实例
2020/01/15 Python
如何利用python web框架做文件流下载的实现示例
2020/06/02 Python
日本食品网上商店:JaponShop.com
2017/11/28 全球购物
德国内衣、泳装和睡衣网上商店:Bigsize Dessous
2018/07/09 全球购物
Antonioli美国在线商店:时尚前卫奢华
2019/07/29 全球购物
中学老师的自我评价
2013/11/07 职场文书
2014年党员承诺书范文
2014/05/20 职场文书
2019交通安全宣传标语集锦!
2019/06/28 职场文书
你对自己的信用报告有过了解吗?
2019/07/09 职场文书
Pytorch中TensorBoard及torchsummary的使用详解
2021/05/12 Python
tree shaking对打包体积优化及作用
2022/07/07 Java/Android