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 相关文章推荐
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
Apr 02 Javascript
jquery如何获取复选框的值
Dec 12 Javascript
js形成页面的一种遮罩效果实例代码
Jan 04 Javascript
JS实现仿百度输入框自动匹配功能的示例代码
Feb 19 Javascript
动态加载js文件简单示例
Apr 21 Javascript
AngularJS包括详解及示例代码
Aug 17 Javascript
Vuejs第十三篇之组件——杂项
Sep 09 Javascript
原JS实现banner图的常用功能
Jun 12 Javascript
捕获未处理的Promise错误方法
Oct 13 Javascript
图文详解vue框架安装步骤
Feb 12 Javascript
从0搭建vue-cli4脚手架
Jun 17 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
Dec 09 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加密解密的代码
2006/10/09 PHP
Ext.data.PagingMemoryProxy分页一次性读取数据的实现代码
2010/04/07 PHP
php多文件上传下载示例分享
2014/02/20 PHP
php实现支付宝当面付(扫码支付)功能
2018/05/30 PHP
最短的javascript:地址栏载入脚本代码
2011/10/13 Javascript
jQuery实现简单二级下拉菜单
2015/04/12 Javascript
jquery实现标签上移、下移、置顶
2015/04/26 Javascript
js实现精确到秒的倒计时效果
2016/05/29 Javascript
JavaScript中Array的实用操作技巧分享
2016/09/11 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
vue.js学习之vue-cli定制脚手架详解
2017/07/02 Javascript
js使用highlight.js高亮你的代码
2017/08/18 Javascript
jQuery选择器选中最后一个元素,倒数第二个元素操作示例
2018/12/10 jQuery
小程序两种滚动公告栏的实现方法
2019/09/17 Javascript
详解Vue中的MVVM原理和实现方法
2020/07/15 Javascript
Vue循环中多个input绑定指定v-model实例
2020/08/31 Javascript
vue项目实现多语言切换的思路
2020/09/17 Javascript
Openlayers3实现车辆轨迹回放功能
2020/09/29 Javascript
如何在现代JavaScript中编写异步任务
2021/01/31 Javascript
Django小白教程之Django用户注册与登录
2016/04/22 Python
python 按不同维度求和,最值,均值的实例
2018/06/28 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
Python matplotlib画曲线例题解析
2020/02/07 Python
python使用docx模块读写docx文件的方法与docx模块常用方法详解
2020/02/17 Python
美国中小型企业领先的办公家具供应商:Office Designs
2016/11/26 全球购物
欧尚俄罗斯网上超市:Auchan俄罗斯
2018/05/03 全球购物
澳大利亚最便宜的网上药房:Chemist Warehouse
2020/01/30 全球购物
12月红领巾广播稿
2014/02/13 职场文书
《陶罐和铁罐》教学反思
2014/02/19 职场文书
大学生自我鉴定书
2014/03/24 职场文书
关于运动会的广播稿
2014/09/22 职场文书
2014年租房协议书范本
2014/10/30 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
餐厅服务员管理制度
2015/08/05 职场文书
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript