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 相关文章推荐
Prototype Object对象 学习
Jul 12 Javascript
Js 中debug方式
Feb 07 Javascript
JavaScript生成验证码并实现验证功能
Sep 24 Javascript
AngularJS中directive指令使用之事件绑定与指令交互用法示例
Nov 22 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
Dec 18 Javascript
javascript 中Cookie读、写与删除操作
Mar 29 Javascript
vue 左滑删除功能的示例代码
Jan 28 Javascript
layui实现数据表格table分页功能(ajax异步)
Jul 27 Javascript
原生js添加一个或多个类名的方法分析
Jul 30 Javascript
layui输入框中只允许输入整数的实现方法
Sep 18 Javascript
js实现数字滚动特效
Dec 16 Javascript
微信小程序实现通讯录列表展开收起
Nov 18 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
Destoon模板制作简明教程
2014/06/20 PHP
完美解决thinkphp验证码出错无法显示的方法
2014/12/09 PHP
PHP面相对象中的重载与重写
2017/02/13 PHP
javascript显示隐藏层比较不错的方法分析
2008/09/30 Javascript
jQuery Ajax文件上传(php)
2009/06/16 Javascript
Extjs在exlipse中设置自动提示的方法
2010/04/07 Javascript
一个基于jquery的图片切换效果
2010/07/06 Javascript
js、css、img等浏览器缓存问题的2种解决方案
2013/10/23 Javascript
JS获得浏览器版本和操作系统版本的例子
2014/05/13 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
2014/10/20 Javascript
NodeJS远程代码执行
2016/08/28 NodeJs
jquery实现文字单行横移或翻转(上下、左右跳转)
2017/01/08 Javascript
NodeJs使用Mysql模块实现事务处理实例
2017/05/31 NodeJs
jsonp跨域请求详解
2017/07/13 Javascript
jquery动态添加以及遍历option并获取特定样式名称的option方法
2018/01/29 jQuery
vue cli升级webapck4总结
2018/04/04 Javascript
vue router 通过路由来实现切换头部标题功能
2019/04/24 Javascript
OpenLayers3实现地图显示功能
2020/09/25 Javascript
Python中用于去除空格的三个函数的使用小结
2015/04/07 Python
使用Python编写一个在Linux下实现截图分享的脚本的教程
2015/04/24 Python
对TensorFlow中的variables_to_restore函数详解
2018/07/30 Python
Python django使用多进程连接mysql错误的解决方法
2018/10/08 Python
浅谈python脚本设置运行参数的方法
2018/12/03 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
Python定义函数时参数有默认值问题解决
2019/12/19 Python
Python3爬虫关于识别检验滑动验证码的实例
2020/07/30 Python
美国领先的宠物用品和宠物食品零售商:Petco
2020/10/28 全球购物
党员年终民主评议的自我评价
2013/11/05 职场文书
同事吵架检讨书
2014/02/05 职场文书
运动会通讯稿500字
2014/02/20 职场文书
药剂专业自荐信范文
2014/04/16 职场文书
班干部演讲稿
2014/04/24 职场文书
班主任师德师风自我剖析材料
2014/10/02 职场文书
三国演义读书笔记
2015/06/25 职场文书
Python标准库之typing的用法(类型标注)
2021/06/02 Python
python index() 与 rindex() 方法的使用示例详解
2022/12/24 Python