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 相关文章推荐
IE和Firefox下javascript的兼容写法小结
Dec 10 Javascript
谈谈关于JavaScript 中的 MVC 模式
Apr 11 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
Sep 22 Javascript
基于javascript实现表格的简单操作
May 21 Javascript
Bootstrap 附加导航(Affix)插件实例详解
Jun 01 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
Feb 14 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
Feb 23 Javascript
layer.open组件获取弹出层页面变量、函数的实例
Sep 25 Javascript
基于VUE的v-charts的曲线显示功能
Oct 01 Javascript
vue element-ui读取pdf文件的方法
Nov 26 Javascript
vue实现购物车加减
May 30 Javascript
vue前端工程的搭建
Mar 31 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使用exec shell命令注入的方法讲解
2013/11/12 PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
2014/06/19 PHP
ThinkPHP实现二级循环读取的方法
2014/11/03 PHP
PHP实现原比例生成缩略图的方法
2016/02/03 PHP
thinkPHP5框架路由常用知识点汇总
2019/09/15 PHP
读jQuery之七 判断点击了鼠标哪个键的代码
2011/06/21 Javascript
Js点击弹出下拉菜单效果实例
2013/08/12 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
DOM基础教程之使用DOM控制表格
2015/01/20 Javascript
js实现可得到不同颜色值的颜色选择器实例
2015/02/28 Javascript
JavaScript中数据结构与算法(五):经典KMP算法
2015/06/19 Javascript
HTML5+jQuery插件Quicksand实现超酷的星际争霸2兵种分类展示效果(附demo源码下载)
2016/05/25 Javascript
Select下拉框模糊查询功能实现代码
2016/07/22 Javascript
jQuery中实现prop()函数控制多选框(全选,反选)
2016/08/19 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
AngularJS入门示例之Hello World详解
2017/01/04 Javascript
JavaScript中的 attribute 和 jQuery中的 attr 方法浅析
2017/01/04 Javascript
js通过Date对象实现倒计时动画效果
2017/10/27 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
2019/01/27 jQuery
viewer.js实现图片预览功能
2020/06/24 Javascript
基于原生JS封装的Modal对话框插件的示例代码
2020/09/09 Javascript
Python中defaultdict与lambda表达式用法实例小结
2018/04/09 Python
如何在python字符串中输入纯粹的{}
2018/08/22 Python
python实现Excel文件转换为TXT文件
2019/04/28 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
2019/08/08 Python
详解Python 循环嵌套
2020/07/09 Python
Python 如何对文件目录操作
2020/07/10 Python
序列化Python对象的方法
2020/08/01 Python
python 实现超级玛丽游戏
2020/11/25 Python
Html5获取高德地图定位天气的方法
2019/12/26 HTML / CSS
德国奢侈品网上商城:Mytheresa
2016/08/24 全球购物
入党积极分子思想汇报范文
2014/01/05 职场文书
生日派对邀请函
2014/01/13 职场文书
医院反腐倡廉演讲稿
2014/09/16 职场文书
公司与个人合作协议书
2016/03/19 职场文书
Python Pandas模块实现数据的统计分析的方法
2021/06/24 Python