Antd组件问题(动态生成Select遇到的问题总结)

最近在跟着老师做一个项目,在项目过程中遇到了动态生成Select的一系列问题,针对解决方案做一个简单的记录。
需求描述如下:

  1. 将后端获取的对象根据varName分类后,根据不同的类别生成Select
  2. 将选择获取到的数据,点击确定后,合并成一个Obj最终存入数组中
遇到问题如下:
  1. 根据varName动态生成Select,显示不同的VarLable及VarItemLable
  2. 点击确定后,Select显示的信息停留,无法更改
选择完成后Value无法清空的解决办法:
  • 问题描述
    Antd组件问题(动态生成Select遇到的问题总结)
    文章图片

    当点击确认选则后,会出现如下情况,此时数据选择结束,但是现实的依然是上次选择的数据,因此,如果再新增或选择完全相同的数据,会导致新增数据为空。
    Antd组件问题(动态生成Select遇到的问题总结)
    文章图片

    当我将Value属性设置为固定值时,又会导致选择后,只现实我设置的固定,交互体验很差。
    Antd组件问题(动态生成Select遇到的问题总结)
    文章图片

    当我参考网上的解决方法将值设置为Undefined的时候,会出现选择后只显示placeholder属性的值,虽然点击成功,但用户看不到。
  • 此时,我又在想为什么不设置一个state数据,通过setState进而控制Select值的显示,但是前文提到我在动态生成多个Select因此一个值,并不足以我们来控制Value的显示情况。
  • 【Antd组件问题(动态生成Select遇到的问题总结)】解决方案
    Antd组件问题(动态生成Select遇到的问题总结)
    文章图片

    我将选择的数据及属性以键值对的方式存储到一个对象中,又由于我时依照varName进行分组后渲染的Select,因此我只需要找到对象中每一个Select对应的VarName的值是否存在?如果不存在则为undefined,此时默认显示的是placeholder属性,然而当选择后,呈现的则是选中的对应的值。如果我们想要点点击后,清空Value,我们只需要清空对象,这样所有的Select便利的都是undefined,完美解决!
    部分数据如下:
  • 原数据中存在重复数据
  • 需要对数据进行排序处理
data: [ { "varItemId": 14, "varItemLabel": "ANT1", "varItemValue": "1", "varName": "ANT", "description": "ANT1", "variableLabel": "天线", "sort": "1", "checked": false }, { "varItemId": 100, "varItemLabel": "TX", "varItemValue": "TX", "varName": "TYPE", "description": "TX", "variableLabel": "类型", "sort": "2", "checked": false }, { "varItemId": 1, "varItemLabel": "2G4", "varItemValue": "2G4", "varName": "G", "description": "2G4", "variableLabel": "频段", "sort": "3", "checked": false }, { "varItemId": 2, "varItemLabel": "5G", "varItemValue": "5G", "varName": "G", "description": "5G", "variableLabel": "频段", "sort": "3", "checked": false }, { "varItemId": 10, "varItemLabel": "11N", "varItemValue": "11N", "varName": "PRO", "description": "11N", "variableLabel": "协议", "sort": "4", "checked": false }, { "varItemId": 5, "varItemLabel": "20M", "varItemValue": "20", "varName": "BW", "varFilter": "", "description": "20M", "variableLabel": "带宽", "sort": "5", "checked": false }, { "varItemId": 289, "varItemLabel": "MCS4", "varItemValue": "4", "varName": "RATE", "varFilter": "11AX,160M", "description": "MCS4", "variableLabel": "速率", "sort": "6", "checked": false }, { "varItemId": 638, "varItemLabel": "5.5M", "varItemValue": "5.5", "varName": "RATE", "varFilter": "11B", "description": "CCK调制", "variableLabel": "速率", "sort": "6", "checked": false },{ "varItemId": 45, "varItemLabel": "CH56", "varItemValue": "5280", "varName": "CH", "varFilter": "5G,20M", "description": "CH56", "variableLabel": "信道", "sort": "7", "checked": false },{ "varItemId": 636, "varItemLabel": "CH58", "varItemValue": "5290", "varName": "CH", "varFilter": "5G,80M", "description": "CH58", "variableLabel": "信道", "sort": "7", "checked": false } ] }

数据处理操作如下:
  1. 引入lodash库中的groupby方法,根据varName进行分组。
const dealedDataByGroup = groupBy(dealedData, (item) => [item.varName]);

  1. 对数据的去重的排序处理,遍历分组后的数据,调用函数如下:
doSrotByAttribute(arr, attribute) { function compare(propertyName) { return function (object1, object2) { const value1 = parseFloat(object1[propertyName]); const value2 = parseFloat(object2[propertyName]); if (value2 < value1) { return 1; } if (value2 > value1) { return -1; } return 0; } }arr.sort(compare(attribute)); return arr; }doUniqueByVarItemLabel(arr) { const hash = {}; arr = arr.reduce((preVal, curVal) => { hash[curVal.varItemLabel] ? '' : hash[curVal.varItemLabel] = true && preVal.push(curVal); return preVal }, []) return arr; } dealedDataByGroup[key] = this.doSrotByAttribute(dealedDataByGroup[key], `varItemLabel`); dealedDataByGroup[key] = this.doUniqueByVarItemLabel(dealedDataByGroup[key]);

  1. 由于不清楚return返回的执行语句中可以遍历Obj的方法,因此我选择了使用concat方法将所有数组存储到一个数组中,两个map嵌套遍历生成Select,最终实现动态生成Select。

    推荐阅读