1.Ant Design

1. 介绍

2. 设计价值观
https://ant.design/docs/spec/...

2.使用的问题和解决方法

1. (前言)Form的适用场合
a.校验和提交
b.数据收集/存数据

在没有分步提交的情况下,使用Form是保存页面现有数据最简单最直接的方法 举例:   

图片描述

在点击保存时调用
form.validateFieldsAndScroll((err, values) => {
    console.log('Received values of form: ', values);
})
看到图片右边Form已经帮我们把值已键值对的形式保存起来了,key是你在使用Form时通过getFieldDecorator
方法与表单进行双向绑定时的参数id,详见ant文档中的Form使用方法

帮我们保存很好,但是当我们点击删除时会不会出现什么问题? demo

2. 使用Form组件后删除时会出现的问题及解决方法

first.gif

可以看到直接删除demoData[i] 无论我们删除第几项 表单中的数据始终是“删除”最后一项。
其实表单中的数据并没有被删除 只是没有缺少key去承接最后一个value而已

解决办法有两种:
一种是删除时手动将form中的key也向上移动一位,例如:删除第一项,写一个方法将Flows0_name赋值为2,Flows1_name赋值为3,Flows2_name赋值为4 以此类推...

这种方法只适合“1对1”删除,当删除的对象内部还存在子对象的时候,例如:(看审批流)
第一个流程适用范围有一个流程,第二个流程适用范围有两个流程,即存在Flows0_Items0_name,和Flows1_Items0_name、Flows1_Items1_name时,若想删除第一个流程适用范围(Flows0_Items0_name)如图:

图片描述

另一种是给数组中的每一项都增加一个flow_flag作为这一项的唯一id,例如:在点击add时,向数组中push一条初始数据时同时将flow_flag push进去,

secend.gif

这种方法“1对1”“1对n”删都可以
注意! <Children {...flowsProps} key={index} {...this.props} /> 的key务必要改成 item.flow_flag

3. 如何实现一个受控选择的树和遇到的问题及解决方法

项目需要一个这样的树:

three.gif

每一个树节点都代表的是一个职级,所以子节点全选中不代表父节点选中,父节点选中代表子节点全选中,这个时候Antd中的树组件就不满足我们项目的需求了,但是他为我们提供了一个让树受控的参数treeCheckStrictly,需要注意的是treeCheckStrictly和treeCheckable共同使用时会使得 labelInValue 强制为 true,意思就是不受控时你选中树节点的value是这样的

persons:["id1","id2","id3",...]

受控后

persons:[
    {value: "id1", label: "name1"},
    {value: "id2", label: "name2"},
    ...
]

受控之后会变成点哪个节点选哪个节点的树。
主要需要下面两个方法:

// 获取某个child_list
    getChildList(list,id){
        if(id==0){
            return list
        }else{
            let newList = [];
            for(let i=0;i<list.length;i++){
                if(list[i].id == id){                                           //[1]
                    newList = list[i].child_list; 
                    return newList;
                }else{
                    if(list[i].child_list.length>0){                            //如果有子节点,拿着子节点去执行this.getChildList(list[i].child_list,id)
                        if(this.getChildList(list[i].child_list,id).length > 0){//如果子节点有返回值,即this.getChildList(list[i].child_list,id)这个方法有返回值(满足[1]),就return
                            return this.getChildList(list[i].child_list,id);
                        };
                    }
                } 
            }
            return newList;
        }
    }
    // 获取某个child_list的所有下一级({value:,label:})
    getNewCheckNodes(newList){
        let ids = [];
        newList.map( item =>{
            ids.push({"value":item.id,"label":item.name});
            if(item.child_list.length!==0){
                this.getNewCheckNodes(item.child_list);
                ids = ids.concat(this.getNewCheckNodes(item.child_list));
            }
        })
        return ids;
    }

思路:在onSelect时可以拿到当前勾选(或取消勾选的value),如果value.value等于根节点id,直接将根节点的child_list作为参数调用getNewCheckNodes()方法即可,如果value.value不等于根节点id,就去执行getChildList()去找到属于当前节点child_list,然后把结果作为参数调getNewCheckNodes(),将子树节点平铺成labelInValue的格式。

需要注意的有两点:
1.是勾选时先去一下重再push。
2.(写时遇到的坑)写这样受控的树时不要用Form了,因为勾选时想给自己setFiledValue是不支持的,上网查是因为

“antd中form表单的setFieldsValue只能设置其他域的值,不能控制自己表单域的值”

所以这里推荐使用state去改变组件的value属性赋值。这个是需要提前注意的地方。


yzbao
626 声望19 粉丝

Uncaught ReferenceError