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 鼠标点击事件及其它捕获
Jun 04 Javascript
jQuery帮助之CSS尺寸(五)outerHeight、outerWidth
Nov 14 Javascript
javascript parseInt() 函数的进制转换注意细节
Jan 08 Javascript
sencha touch 模仿tabpanel导航栏TabBar的实例代码
Oct 24 Javascript
jQuery中操控hidden、disable等无值属性的方法
Jan 06 Javascript
Jquery实现Div上下移动示例
Apr 23 Javascript
Javascript中封装window.open解决不兼容问题
Sep 28 Javascript
百度搜索框智能提示案例jsonp
Nov 28 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
Vue实现table上下移动功能示例
Feb 21 Javascript
一文快速了解JQuery中的AJAX
May 31 jQuery
nuxt+axios实现打包后动态修改请求地址的方法
Apr 22 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 网络开发详解之远程文件包含漏洞
2010/04/25 PHP
PHP 图片水印类代码
2012/08/27 PHP
ThinkPHP模板中数组循环实例
2014/10/30 PHP
php结合md5实现的加密解密方法
2016/01/25 PHP
PHP5.3连接Oracle客户端及PDO_OCI模块的安装方法
2016/05/13 PHP
PHP房贷计算器实例代码,等额本息,等额本金
2017/04/01 PHP
PHP读取文件或采集时解决中文乱码
2021/03/09 PHP
extjs fckeditor集成代码
2009/05/10 Javascript
javascript 数组学习资料收集
2010/04/11 Javascript
JS中的this变量的使用介绍
2013/10/21 Javascript
jQuery实现简单下拉导航效果
2015/09/07 Javascript
js滑动提示效果代码分享
2016/03/10 Javascript
Web程序员必备的7个JavaScript函数
2016/06/14 Javascript
JS中Select下拉列表类(支持输入模糊查询)功能
2017/01/17 Javascript
Vue中的Vux配置指南
2017/12/08 Javascript
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
2019/04/01 Javascript
VUE脚手架具体使用方法
2019/05/20 Javascript
vue中组件通信的八种方式(值得收藏!)
2019/08/09 Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
2019/09/14 Javascript
封装 axios+promise通用请求函数操作
2020/08/11 Javascript
Vue+Element ui 根据后台返回数据设置动态表头操作
2020/09/21 Javascript
Echarts在Taro微信小程序开发中的踩坑记录
2020/11/09 Javascript
[19:59]2014DOTA2国际邀请赛 IG战队纪录片
2014/08/07 DOTA
详解Python的Django框架中的中间件
2015/07/24 Python
python将list转为matrix的方法
2018/12/12 Python
python实现将一维列表转换为多维列表(numpy+reshape)
2019/11/29 Python
python读取图像矩阵文件并转换为向量实例
2020/06/18 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
Ivory Isle Designs美国/加拿大:婚礼和活动文具公司
2018/08/21 全球购物
Hudson Jeans官网:高级精制牛仔裤
2018/11/28 全球购物
美国厨房和园艺工具网上商店:Nestneed
2019/08/24 全球购物
Java中compareTo和compare的区别
2016/04/12 面试题
小学生田径运动会广播稿
2014/09/11 职场文书
2014红色之旅心得体会
2014/10/07 职场文书
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis