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跨浏览器实现将字符串转化为xml对象的方法
Sep 25 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
Sep 23 Javascript
node.js中使用socket.io的方法
Dec 15 Javascript
JavaScript测试工具之Karma-Jasmine的安装和使用详解
Dec 03 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
May 17 Javascript
JS触发服务器控件的单击事件(详解)
Aug 06 Javascript
修改ligerui 默认确认按钮的方法
Dec 27 Javascript
JS验证码实现代码
Sep 14 Javascript
webpack3里使用uglifyjs压缩js时打包报错的解决
Dec 13 Javascript
通过实例解析JavaScript for in及for of区别
Jun 15 Javascript
vue动态绑定style样式
Apr 20 Vue.js
ant design vue的form表单取值方法
Jun 01 Vue.js
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学习笔记之三 数据库基本操作
2011/01/17 PHP
php中实现进程锁与多进程的方法
2016/09/18 PHP
php 猴子摘桃的算法
2017/06/20 PHP
PHP实现动态获取函数参数的方法示例
2018/04/02 PHP
PHP实现一维数组与二维数组去重功能示例
2018/05/24 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
2018/07/21 PHP
js 设置选中行的样式的实现代码
2010/05/24 Javascript
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
使用非html5实现js板连连看游戏示例代码
2013/09/22 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
JavaScript中Cookie操作实例
2015/01/09 Javascript
setinterval()与clearInterval()JS函数的调用方法
2015/01/21 Javascript
javascript设计模式之单体模式学习笔记
2017/02/15 Javascript
JS基于正则表达式的替换操作(replace)用法示例
2017/04/28 Javascript
angular.js4使用 RxJS 处理多个 Http 请求
2017/09/23 Javascript
JS对象与json字符串相互转换实现方法示例
2018/06/14 Javascript
解决Can't find variable: SockJS vue项目的问题
2020/09/22 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
kNN算法python实现和简单数字识别的方法
2014/11/18 Python
Python实现约瑟夫环问题的方法
2016/05/03 Python
python常用函数详解
2016/09/13 Python
Python 实现域名解析为ip的方法
2019/02/14 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
Python 正则表达式 re.match/re.search/re.sub的使用解析
2019/07/22 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
2020/06/29 Python
Python常用模块函数代码汇总解析
2020/08/31 Python
美国婴儿和儿童服装购物网站:PatPat
2020/10/01 全球购物
俄罗斯极限运动网上商店:Board Shop №1
2020/12/18 全球购物
this关键字的含义
2015/04/08 面试题
医院总经理职责
2013/12/26 职场文书
2014年综治宣传月活动总结
2014/04/28 职场文书
家长高考寄语
2015/02/27 职场文书
单位更名证明
2015/06/18 职场文书
运动会跳远广播稿
2015/08/19 职场文书
用python开发一款操作MySQL的小工具
2021/05/12 Python