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中简单的实现像C#中using功能(有源码下载)
Jan 09 Javascript
ASP小贴士/ASP Tips javascript tips可以当桌面
Dec 10 Javascript
js去空格技巧分别去字符串前后、左右空格
Oct 21 Javascript
javascript关于运动的各种问题经典总结
Apr 27 Javascript
js实现的动画导航菜单效果代码
Sep 10 Javascript
canvas实现图像放大镜
Feb 06 Javascript
在页面中引入js的两种方法(推荐)
Aug 29 Javascript
JS去掉字符串末尾的标点符号及删除最后一个字符的方法
Oct 24 Javascript
浅谈mvvm-simple双向绑定简单实现
Apr 18 Javascript
jQuery AJAX 方法success()后台传来的4种数据详解
Aug 08 jQuery
微信小程序制作扭蛋机代码实例
Sep 24 Javascript
jQuery实现动态加载瀑布流
Sep 01 jQuery
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/12/06 PHP
PHP面向对象编程快速入门
2006/12/14 PHP
PHP中查询SQL Server或Sybase时TEXT字段被截断的解决方法
2009/03/10 PHP
PHP实现数据库统计时间戳按天分组输出数据的方法
2017/10/10 PHP
斜45度寻路实现函数
2009/08/20 Javascript
一个报数游戏js版(约瑟夫环问题)
2010/08/05 Javascript
使用隐藏的new来创建对象
2011/03/29 Javascript
Json对象与Json字符串互转(4种转换方式)
2013/03/27 Javascript
第一次接触JS require.js模块化工具
2016/04/17 Javascript
AngularJS入门教程之 XMLHttpRequest实例讲解
2016/07/27 Javascript
输入法的回车与消息发送快捷键回车的冲突解决方法
2016/08/09 Javascript
Vue.js路由组件vue-router使用方法详解
2016/12/02 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
Vue.js实现微信过渡动画左右切换效果
2017/06/13 Javascript
Vue路由对象属性 .meta $route.matched详解
2019/11/04 Javascript
JavaScript canvas实现跟随鼠标移动小球
2021/02/09 Javascript
python实现的一只从百度开始不断搜索的小爬虫
2013/08/13 Python
Python读写Excel文件方法介绍
2014/11/22 Python
python使用urllib2实现发送带cookie的请求
2015/04/28 Python
python递归计算N!的方法
2015/05/05 Python
查看Django和flask版本的方法
2018/05/14 Python
python自动化之Ansible的安装教程
2019/06/13 Python
用Python实现将一张图片分成9宫格的示例
2019/07/05 Python
pytorch获取模型某一层参数名及参数值方式
2019/12/30 Python
深入了解NumPy 高级索引
2020/07/24 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
介绍一下write命令
2014/08/10 面试题
EJB实例的生命周期
2016/10/28 面试题
数据保密承诺书
2014/06/03 职场文书
园艺专业毕业生求职信
2014/09/02 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
2019个人年度目标制定攻略!
2019/07/12 职场文书
为什么node.js不适合大型项目
2021/04/28 Javascript
JavaScript实现简单计时器
2021/06/22 Javascript
Python编程super应用场景及示例解析
2021/10/05 Python
「地球外少年少女」BD发售宣传CM公开
2022/03/21 日漫