Vue+ElementUI , el-casecader级联面板参数回显

目录标题

  • 背景
  • 一、 级联面板返回的数据格式说明
  • 二、级联面板单选(解决)
  • 三、级联面板多选(妥协)

背景

ElementUI中Cascader 级联选择器组件作为Select 选择器组件的补充,可以帮助我们方便且友好的显示多层级数据的筛选。

但级联面板的返回数据在用于数据回显时,却显得比较麻烦。因此,现在将记录一下自己在做级联面板数据回显时的方案。

一、 级联面板返回的数据格式说明

通过ElementUI中在线运行工具的调试,可以看到级联面板返回给我们的结果,是一个包含从祖宗节点到选中节点完整路径的数组,如下图所示,选中 "input输入框"时,会返回给我们一个记录选中label的value的数组:[“zujian”, “form”, “input”]。
Vue+ElementUI , el-casecader级联面板参数回显_第1张图片
Vue+ElementUI , el-casecader级联面板参数回显_第2张图片
多选时的数据格式也是如此,只不过变成了一个二维数组,如下图所示。
Vue+ElementUI , el-casecader级联面板参数回显_第3张图片

那么在数据回显时,我们必须要给级联面板的绑定值设定为完整路径数组的格式,才可以正确回显。如果后端能够把级联面板选中的值原样保存起来,那么回显就不存在任何问题了,但通常事与愿违。后端通常只会给我们返回当前选中节点的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();
   }
},

三、级联面板多选(妥协)

对于单选,我们可以直接构造数组,但对于多选,构造二维数组比较麻烦,个人最终选择了妥协,让后端帮忙开辟一个字段,专门用来存储整个二维数组的值。
解决方式如下:

  1. 前端:使用JSON.stringify(value),将二维数组转换为JSON格式的字符串。数据回显时,取得后端传来的字符串,使用JSON.parse(value),即可直接填入级联面板的参数中。
  2. 后端:使用JSONArray.fromObject(value);对字符串进行解析,将这个二维数组以字符串形式存在数据库中;

这里提供一个方法,可以同时返回原二维数组数据和不重复的节点数据,我这里后端原始的方法就是对用逗号隔开的数据拆串后,进行遍历,为了改动不大,因此这里也使用这种数据形式返回,也可以直接返回不重复节点值的数组,这个因人而异。

  1. 写法一:
/**
* 处理级联面板绑定的数据
* @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;
}
  1. 写法二,练习一下stream流操作:
/**
* 处理级联面板绑定的数据
* @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;
}

你可能感兴趣的:(前端,开发中的小问题记录)