问题(耗时我一天多):
编辑时回显数据。
两种情况:emitPath分别为false和True。
同时,checkStrictly始终为true(即允许选中的是中间层节点)。
一个是省市数据:
省市数据采取emitPath为True。
一个是部门数据:
部门数据采取emitPath为False。
后端处理:
针对省市数据,后端返回省市列表。形如["北京市","东城区"]。注意,是列表
针对部门数据,后端只返回一个部门的id值,并且非列表。
编辑回显规则(尽量不要设leaf,没必要。注意是label,value和children):
懒加载的编辑回显,我通过一天反复实验,总结出三条规则:
规则1.第一:lazyload中resolve的那个数据,其层次,必须能够与要显示的编辑回显值对应(能利用resolve的数据字典,搜索出要显示的回显值列表),并且层次大于回显值层次。比如,resolve的是省市区,那么回显值可以是只到省,也可以是省市,也可以是省市区。
即回显值的列表长度必须小于等于resolve数据的层次数
规则2.第二:当修改后端返回的部门数据的id值时,即令this.form.dept_id,改为列表时,组件会默认执行点击过程(即,可以利用alert输出一个node.level值。),这个默认的点击过程,至少执行一次。
比如,你传回的部门id是6,你为了能够满足前述规则1,通过搜索列表,将回显值改为列表["12","6"]。那么当改完以后,组件会默认执行点击过程(非node.level===0对应的lazyload加载过程),比如node.level==1。
规则3.当涉及后端数据返回时,由于执行的是Promise过程,在then中获取返回数据,需要写上await和async,避免出现数据未resolve,而组件已经加载完毕的情形(具体可以自行测试。不一定需要await和async。)
针对不修改回显值情形的籍贯数据(一次加载34省份数据,太大,需要懒加载)
以avue.js的option为例,下面是一个完整的option某个列籍贯的定义。
--》注解:
1.首先是加载el-cascader组件时,会在lazyload中执行node.level==0对应的加载过程,这个时候,我们需要利用safe.form.domicile(safe是this)方法来判定当前是编辑还是新增。
判断方法为:
if (!(safe.form.domicile === null || safe.form.domicile === undefined)) {
即有无值传入。
当无回显值列表传入的时候,我们在node.level==0中只加载最高一级的省数据。当有回显值传入时,为了回显,我们将该省的所有市数据全部resolve,保证resolve的数据层次大于回显值列表的宽度,保证回显。
2.其次,对于所有非node.level=0的情形,先判定当前node.data.childen有无数据(编辑回显时,resolve的数据已经有了。此时resolve([]),避免点击北京后,重复出现多个类似东城区的数据子列表。),如果没有,再获取value,利用getcity方法获取子数据即可。
《-- 注解。
{
filters: true,
sortable: "custom",
label: "籍贯",
cell: true,
prop: "domicile",
xiaojieimport: true,
type: "cascader",
checkStrictly: true,
lazy: true,
formatter: (val, value, label) => {
var sssss = "";
// alert(JSON.stringify(value));
// alert(value[0] + value[1]);
if (value == null) {
return "";
} else {
if (value instanceof Array) {
value.forEach((item) => {
sssss += item;
});
}
}
return sssss;
},
lazyLoad: (node, resolve) => {
// 这里要注意编辑回显
var result = [];
if (node.level === 0) {
// alert("0");
result = getProvince();
// alert(JSON.stringify(safe.form.domicile));
// alert(JSON.stringify(result));
// alert(safe.form.domicile);
if (!(safe.form.domicile === null || safe.form.domicile === undefined)) {
if (safe.form.domicile.length > 0) { // 编辑回显
// alert("编辑回显");
// 事实证明,只要result中的比传入的多即可。
// alert(safe.form.domicile[1]);
var childrenList = getCity(safe.form.domicile[0]);
// alert(JSON.stringify(childrenList));
var new_result = [];
result.forEach((item) => {
if (item["value"] === safe.form.domicile[0]) {
item["children"] = childrenList;
}
new_result.push(item);
// alert(JSON.stringify(new_result));
});
result = new_result;
}
}
// alert(JSON.stringify(result));
resolve(result);
} else {
alert("回显会自动执行");
// 为了避免编辑回显时,已经加载了许多result,我们需要避免重复加载children
if (!("children" in node.data && node.data["children"] !== [])) {
node.data["children"] = [];
result = getCity(node.data.value); // 该函数可以继续获取子city
resolve(result);
} else {
resolve([]);
}
}
},
search: true
},
针对需要修改回显值情形的部门数据(从后端返回数据,位于then中执行回显)
我们存储的部门数据只是一个子部门的id(可以为中间部门。)比如,中央部、宣传办。可以是中央部的id,也可以是宣传部子部门的id。
虽然利用emitPath为false,将el-cascader的数据,只传一个值到后端。后端返回一个数。
但是,如果想顺利回显出“中央部/宣传部”的形式,必须转为列表。见前述回显规则1。
具体代码如下:
--》注解:
1.首先是加载el-cascader组件时,会在lazyload中执行node.level==0对应的加载过程,这个时候,我们需要利用safe.form.dept_id(safe是this)方法来判定当前是编辑还是新增。
判断方法同前。即有无值传入。
当无回显值列表传入的时候,我们只加载第一层部门数据。当有回显值传入时,我们利用递归方法,在字典数据中寻找该id,记录path,从而将一个部门id,变为能够加载回显的部门列表数据。具体见规则1。
然后,再一次执行获取全部部门数据的result,并且只resolve最高一层。(注意,这个能同于前述籍贯数据。因为籍贯数据中,不涉及修改回显值,所以,不存在默认点击的情形。而这里如果resolve全部数据,会造成只有顶层部门的回显值,无法成功回显。具体原因不明。可自行测试。)。
2.其次,对于所有非node.level=0的情形,这里不判定有无子数据,而是要直接搜寻所有子数据,并resolve。(具体原因不明,可自行测试)
3.针对需要修改回显值的情形,为什么用上述两个步骤使用,具体原因不明,但是绝对不同于前述籍贯数据(emitPath=true)。可能是vue.js中的一个bug。大家将就使用。
欢迎高手指导。
《-- 注解。
{
filters: true,
sortable: "custom",
label: "办公室",
type: "cascader",
cell: true,
prop: "dept_id",
search: true,
ref: "office",
checkStrictly: true,
emitPath: false,
xiaojieimport: true,
lazy: true,
formatter: (val, value, label) => {
if ("dept_name" in val) {
return val["dept_name"];
} else {
return "";
}
},
lazyLoad: async(node, resolve) => {
var result = [];
if (node.level === 0) {
// alert("node level 0");
if (!(safe.form.dept_id === null || safe.form.dept_id === undefined)) {
// 当等于1的时候 这个取值的过程不要放到
var l = [];
l.push(safe.form.dept_id);
safe.form.dept_id = l;
// alert("Yyyy");
await getTreeselect_zhidingbumen().then(function(res) {
// alert(JSON.stringify(res));
result = res;
var objj = {
flag: true,
path: [],
result: [],
once: false,
children: []
};
var path = [];
findItem(result, safe.form.dept_id, objj, path);
if (objj.path.length != 1) {
// alert("Xxxx");
safe.form.dept_id = objj.path; //将部门数据变为部门列表数据
}
});
await getTreeselect_zhidingbumen().then(function(res) {
// alert(JSON.stringify(res));
result = res;
for (var index in result) {
if ("children" in result[index]) {
delete result[index]["children"];
}
result[index]["children"] = [];
}
resolve(result);
});
} else {
// 非编辑回显时,只加载第一层数据
getTreeselect_zhidingbumen().then(function(res) {
// alert(JSON.stringify(res));
result = res;
for (var index in result) {
if ("children" in result[index]) {
delete result[index]["children"];
}
result[index]["children"] = [];
}
resolve(result);
});
}
} else {
// 当执行完一次修改值的时候。
alert("回显");
alert(node.level);
alert(JSON.stringify(node.data));
var pickValue = node.data.value;
alert(pickValue);
getTreeselect_zhidingbumen().then(function(res) {
var objj = {
flag: true,
path: [],
result: [],
once: false,
children: []
};
var path = [];
// 当找到以后,返回该点击数据的children值。
findItem(res, pickValue, objj, path);
// alert(JSON.stringify(objj.children));
if ("children" in objj) {
objj.children.forEach((item) => {
if ("children" in item) {
delete item["children"];
}
});
}
// alert(JSON.stringify(objj.children));
resolve(objj.children);
});
}
}
},
你永远不知道未来会有什么,做好当下。技术改变世界,欢迎交流。