前段时间项目中遇到一个需求,效果如下图:
这个红框里面的是通过一个数组渲染出来的,后端给过来的数据格式是一个一维数组:
[{
title: '意图',
label: '搭讪',
value: '1'
}, {
title: '方向',
label: '出',
value: '3’
}, {
title: '意图',
label: '搭讪',
value: '1'
}]
前端需要将数组通过title来升级为二维数组,这样才能map渲染出上面要的效果。不同的title为不同的分组。这个升级的的方法我是这样写得:
const createClssifyOption = (arr) => {
let result = [];
let map = new Map();
for (let i = 0; i < arr.length; i++) {
if (map.has(arr[i].category)) {
result[result.length - 1].options.push({
label: arr[i].labelName,
value: arr[i].labelId.toString(),
});
} else {
map.set(arr[i].category, 1);
result.push({
title: arr[i].category,
defaultValue: [],
options: [
{
label: arr[i].labelName,
value: arr[i].labelId.toString(),
},
],
});
}
if (arr[i].checked) {
result[result.length - 1].defaultValue.push(arr[i].labelId.toString());
}
}
return result;
};
转换之后就拿到了我想要的数据格式,如下:
注意:defaultValue是为了配合antd的checkboxgroup的API,不清楚可以看官方文档。
通过这个数组渲染出页面没有问题。
设定defaultValue后问题来了:
每次翻页页面显示的都是上一次请求过来的数据,而断点打印显示setState也生效了。
表示很无语,,,但是但是,我用了value之后就可以实现实时显示了,目测是antd的bug。
接下来又有问题了,checkbox的事件如何绑定呢?map出来的只能写一个方法来处理。
苦思冥想之后,方法如下:
结合js中对象更改内存地址不会变的原理,直接更改当前item中的defaultValue
// v是每次选中的时候当前checkboxgroup的选中值的集合
// i是当前的checkboxgroup的索引
const chooseClassify = (v, i) => {
this.setState({
classifyArr: this.state.classifyArr.map((item, index) => {
console.log(index, i);
if (index === i) {
return {
...item,
defaultValue: v,
};
}
return item;
}),
});
};
然后每次保存的时候,将渲染数组中的defaultValue push到一个数组中传给后端就ok了。
问题搞定,,,晚饭加鸡腿!!