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 相关文章推荐
简单实用的反馈表单无刷新提交带验证
Nov 15 Javascript
jQuery中ajax的load()与post()方法实例详解
Jan 05 Javascript
jQuery prototype冲突的2种解决方法(附demo示例下载)
Jan 21 Javascript
教你用十行node.js代码读取docx的文本
Mar 08 Javascript
BootStrap 导航条实例代码
May 18 Javascript
关于vue.js组件数据流的问题
Jul 26 Javascript
JS实现的加减乘除四则运算计算器示例
Aug 09 Javascript
JS实现图片居中悬浮效果
Dec 25 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
May 15 Javascript
JavaScript数组基于交换的排序示例【冒泡排序】
Jul 21 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
Dec 06 Javascript
js+canvas绘制图形验证码
Sep 21 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
smarty静态实验表明,网络上是错的~呵呵
2006/11/25 PHP
php中在PDO中使用事务(Transaction)
2011/05/14 PHP
深入php内核之php in array
2015/11/10 PHP
用javascript实现读取txt文档的脚本
2007/07/20 Javascript
javascript 页面只自动刷新一次
2009/07/10 Javascript
JavaScript 面向对象之命名空间
2010/05/04 Javascript
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
分享一款基于jQuery的视频播放插件
2014/10/09 Javascript
js实现不提交表单获取单选按钮值的方法
2015/08/21 Javascript
AngularJs实现ng1.3+表单验证
2015/12/10 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
轻松实现jquery选项卡切换效果
2016/10/10 Javascript
老生常谈js数据类型
2017/08/03 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
微信小程序开发注意指南和优化实践(小结)
2019/06/21 Javascript
解决vue.js提交数组时出现数组下标的问题
2019/11/05 Javascript
echarts.js 动态生成多个图表 使用vue封装组件操作
2020/07/19 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
[03:14]2014DOTA2西雅图国际邀请赛 EG战队巡礼
2014/07/07 DOTA
python实现桌面托盘气泡提示
2019/07/29 Python
python多进程并行代码实例
2019/09/30 Python
解决python中显示图片的plt.imshow plt.show()内存泄漏问题
2020/04/24 Python
python语言time库和datetime库基本使用详解
2020/12/25 Python
python热力图实现简单方法
2021/01/29 Python
html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法
2013/01/09 HTML / CSS
Bowflex美国官方网站:高级家庭健身器材
2017/12/22 全球购物
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
2013/03/30 面试题
母亲七十大寿答谢词
2014/01/18 职场文书
公司前台辞职报告
2014/01/19 职场文书
社区道德讲堂实施方案
2014/03/21 职场文书
学校政风行风评议工作总结
2014/10/21 职场文书
介绍信的格式
2015/01/30 职场文书
护士自我推荐信范文
2015/03/24 职场文书
学校运动会开幕词
2016/03/03 职场文书