ElementUI中Cascader 级联选择器组件作为Select 选择器组件的补充,可以帮助我们方便且友好的显示多层级数据的筛选。
但级联面板的返回数据在用于数据回显时,却显得比较麻烦。因此,现在将记录一下自己在做级联面板数据回显时的方案。
通过ElementUI中在线运行工具的调试,可以看到级联面板返回给我们的结果,是一个包含从祖宗节点到选中节点完整路径的数组,如下图所示,选中 "input输入框"时,会返回给我们一个记录选中label的value的数组:[“zujian”, “form”, “input”]。
多选时的数据格式也是如此,只不过变成了一个二维数组,如下图所示。
那么在数据回显时,我们必须要给级联面板的绑定值设定为完整路径数组的格式,才可以正确回显。如果后端能够把级联面板选中的值原样保存起来,那么回显就不存在任何问题了,但通常事与愿违。后端通常只会给我们返回当前选中节点的value和整个树形结构的数组,需要我们自行构造完整路径的数组。
在只有当前选中节点的value和整个树形结构的数组时,前端构造完整路径数组的方式,类似于遍历一颗多叉树,从根节点开始记录下路径,直到找到选中节点:
// 构造级联面板的选中参数
buildParam(){
let result = []
let searchFlag = {flag: false}
this.buildSingleSeletedCasecaderVal(root, row.id, result, searchFlag)
console.log(result)
// 当我们需要选中当前节点的上一级节点时,可以从结果中弹出最后一个,或者重新遍历都可以
// result.pop()
}
/**
1. 构造单选级联面板选中数据的完整路径
2. root : 全部数据,一颗以id='0' 为根节点的多叉树
3. target: 寻找的目标节点id,例如 id = '2'
4. res: 存放结果路径,例如:["0","1","2"]
5. searchFlag : 是否找到,找到即返回递归
*/
buildSingleSeletedCasecaderVal(root, target, res, searchFlag) {
if (searchFlag.flag) {
return
}
if (root.id == target) {
res.push(target)
this.$set(searchFlag, "flag", true)
return;
} else {
res.push(root.id)
let children = root.children
if (children != undefined && children.length != 0) {
children.forEach(item => {
this.buildSingleSeletedCasecaderVal(item, target, res, searchFlag)
})
}
if (searchFlag.flag) {
return
}
res.pop();
}
},
对于单选,我们可以直接构造数组,但对于多选,构造二维数组比较麻烦,个人最终选择了妥协,让后端帮忙开辟一个字段,专门用来存储整个二维数组的值。
解决方式如下:
这里提供一个方法,可以同时返回原二维数组数据和不重复的节点数据,我这里后端原始的方法就是对用逗号隔开的数据拆串后,进行遍历,为了改动不大,因此这里也使用这种数据形式返回,也可以直接返回不重复节点值的数组,这个因人而异。
/**
* 处理级联面板绑定的数据
* @param casecaderval JSONArray格式的数据
* @return map( "casecadeval":"[[a,b],[a,c]]","list(ArrayList)":"[a,b,c]","vals":"a,b,c")
*/
public Map handleCasecaderValue(String casecaderval){
Map<String,Object> res = new HashMap<>();
JSONArray casecadervals = JSONArray.fromObject(casecaderval);
List<String> list = new ArrayList<>();
casecadervals.stream().forEach(item->{
((JSONArray)item).forEach(i->{
if(!list.contains(i)){
list.add( (String)i );
}
});
});
StringBuilder vals = new StringBuilder();
list.forEach(item->{
vals.append(item + ",");
});
res.put("casecaderval",casecaderval);
res.put("list",list);
res.put("vals",vals.substring(0,vals.length()-1));
return res;
}
/**
* 处理级联面板绑定的数据
* @param casecaderval JSONArray格式的数据
* @return map( "casecadeval":"[[a,b],[a,c]]","list(ArrayList)":"[a,b,c]","vals":"a,b,c")
*/
public Map handleCasecaderValue(String casecaderval){
Map<String,Object> res = new HashMap<>();
JSONArray menuIds = JSONArray.fromObject(casecaderval);
//使用set集合来存放不重复元素
Set set = new HashSet<>();
menuIds.stream().forEach(item->{
set.addAll(Arrays.asList(((JSONArray) item).toArray()));
});
res.put("casecaderval",casecaderval);
res.put("list",set.stream().map(i -> i).collect(Collectors.toList()));
res.put("vals",set.stream().map(i -> i).collect(Collectors.joining(",")).toString());
return res;
}