React计算antd的TreeSelect组件所选中的子节点数量

antd的TreeSelect组件在处理例如公司层级、学科系统、分类目录等等的树形选择需求时很好用。

在使用这个组件时,我们往往需要获取所选中的所有节点以及所选中的所有子节点的数量。

查看TreeSelect的api找到了组件的选中回调方法onChange


onChange.png

在理解onChange方法的参数含义前,要先知道TreeSelect组件的数据格式


treeData.png

onChange方法有三个参数,value表示所选中的节点的value字段值,label代表所选中的节点的title字段值。而最后一个extra参数是获取所选中子节点数量的关键,它是一个Object对象。

通过查看extra的数据,找到了allCheckedNodes这个字段。这个字段里放置着所有被选中的节点的数据。其格式如下

[
    {
        "node":{
            "key":"1",
            "ref":null,
            "props":{
                "title":"全体老师",
                "value":"1",
                "children":[
                    {
                        "key":"1-1",
                        "ref":null,
                        "props":{
                            "title":"老师1",
                            "value":"1-1",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-2",
                        "ref":null,
                        "props":{
                            "title":"老师2",
                            "value":"1-2",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-3",
                        "ref":null,
                        "props":{
                            "title":"老师3",
                            "value":"1-3",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-4",
                        "ref":null,
                        "props":{
                            "title":"老师4",
                            "value":"1-4",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-5",
                        "ref":null,
                        "props":{
                            "title":"老师5",
                            "value":"1-5",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-6",
                        "ref":null,
                        "props":{
                            "title":"老师6",
                            "value":"1-6",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-7",
                        "ref":null,
                        "props":{
                            "title":"老师7",
                            "value":"1-7",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-8",
                        "ref":null,
                        "props":{
                            "title":"老师8",
                            "value":"1-8",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    },
                    {
                        "key":"1-9",
                        "ref":null,
                        "props":{
                            "title":"老师9",
                            "value":"1-9",
                            "children":[

                            ]
                        },
                        "_owner":null,
                        "_store":{

                        }
                    }
                ]
            },
            "_owner":null,
            "_store":{

            }
        },
        "pos":"0-1",
        "children":[
            {
                "pos":"0-1-0"
            },
            {
                "pos":"0-1-1"
            },
            {
                "pos":"0-1-2"
            },
            {
                "pos":"0-1-3"
            },
            {
                "pos":"0-1-4"
            },
            {
                "pos":"0-1-5"
            },
            {
                "pos":"0-1-6"
            },
            {
                "pos":"0-1-7"
            },
            {
                "pos":"0-1-8"
            }
        ]
    }
]

分析发现,allCheckedNodes对象里的pos字段内容是当前被选中的节点的key值,而children字段是这个节点的被选中的所有子节点的集合数组,而children内的对象又有可能有下一层级的子节点。

为了计算这种嵌套的多层级关系的子节点数量,我们需要用到递归方法。

方法思路是,一层一层的去看当前对象有没有children字段,如果没有,说明它是子节点,那直接让数量加一;如果有,则说明是父节点,则递归调用方法去取其子节点内的数据。经过这样的递归取数,就能计算出所有被选中的子节点的数量了。

方法代码如下:


export const getCheckedNodes = (extra) => {
    let checkedNodes = extra.allCheckedNodes || [extra.triggerNode]
    // let count = getCheckedCount(checkedNodes)
    if (isObjEmpty(checkedNodes)) {
        checkedNodes = []
    }
    checkedNodes = getNodes(checkedNodes)
    console.log('checkNodes', checkedNodes)
    return {checkedNodes, count: checkedNodes.length}
}

export const getNodes = (checkedNodes) => {
    if (!isObjEmpty(checkedNodes)) {
        let childNodes = []
        for (let i = 0; i < checkedNodes.length; i++) {
            let checkedNode = checkedNodes[i]
            if (checkedNode) {
                if (checkedNode.node && checkedNode.node.props) {
                    const checkProps = checkedNode.node.props
                    if (!isObjEmpty(checkProps.children)) {
                        checkedNode = checkProps.children
                        childNodes = childNodes.concat(getNodes(checkedNode))
                    } else {
                        let exist = false
                        for (let j = 0; j < childNodes.length; j++) {
                            if (checkProps && checkProps.value == childNodes[j].value) {
                                exist = true
                                break
                            }
                        }
                        if (!exist) {
                            childNodes.push(checkProps)
                        }
                        continue
                    }
                } else {
                    if (checkedNode.props) {
                        const checkProps = checkedNode.props
                        if (!isObjEmpty(checkProps.children)) {
                            checkedNode = checkProps.children
                            childNodes = childNodes.concat(getNodes(checkedNode))
                        } else {
                            let exist = false
                            for (let j = 0; j < childNodes.length; j++) {
                                if (checkProps && checkProps.value == childNodes[j].value) {
                                    exist = true
                                    break
                                }
                            }
                            if (!exist) {
                                childNodes.push(checkProps)
                            }
                            continue
                        }
                    }
                }
            } else {
                continue
            }
        }
        return childNodes
    } else {
        return []
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 2018年1月19一21日 1.感恩爸妈的养育之恩,帮助照顾儿子。 2.感恩儿子,磨练我成长,给我幸福。两天时间全...
    冯梓源阅读 152评论 0 0
  • 文|峰语 戴上耳机 用音乐与世界隔离 眼前和内心的多了几抹美好 植入另类的情感 生活仿佛变成了电影​​​
    代峰语阅读 94评论 0 0