1.1场景:
当主子表详情页面中的明细表体行中的某列是通过查询yonql获取值时,如果用公式实现,每行的数据加载都会去执行一次yonql。如果加载的数据量比较大时,就会出现卡顿且浏览器崩溃的情况。
如何解决这个问题,首先尽量不在子表中使用公式计算,推荐通过写脚本的方式代替公式计算。如果涉及到每行都有查询yonql操作,要用分页的方式去执行查询,分批返回后再做匹配赋值处理,减少查询yonql的次数。 具体操作步骤如下:
1.2操作步骤:
1.首先在表体行的右上方添加触发按钮
2.编写脚本,主要包括:分页处理、同步调用api函数、返回结果匹配赋值、查询yonql的api函数
//前端分页处理、同步调用api函数以及匹配赋值处理脚本
viewModel.get('button27vb') && viewModel.get('button27vb').on('click', function (data) {
// 单击按钮触发
let kehufenlei = viewModel.get('kehufenlei').getValue();//客户分类【yonql查询条件】
//处理分页
var gridModel = viewModel.get("X00301List");//实体清单中的子表集合属性
//获取表格当前页面所有的行数据
const rowAllDatas = gridModel.getRows();
if(rowAllDatas==0){
cb.utils.alert("请输入表体行数据");
return;
}
let arrData = []; //存储每页的结果
let pageSize = 100; //每页数量【可根据实际情况进行调整】
let rowSize = rowAllDatas.length;
let totalNum = Math.ceil(rowSize/pageSize); //总分页
let productConditions = "";
let productConditionsArr = []; //存储生成条件的数组
//下面的wuliaobianma为表体行的必填项且唯一标识类的字段名,使用时根据实际情况替换
if(rowAllDatas[rowSize-1].wuliaobianma==undefined||rowAllDatas[rowSize-1].wuliaobianma==null){
delete rowAllDatas[rowSize-1]; //移除最后一行空数据
rowSize = rowSize-1;
}
for(let i=0;i<rowSize;i++){
if(rowAllDatas[i].wuliaobianma==undefined||rowAllDatas[i].wuliaobianma==null){
let currentRowPage = i+1; //页面显示的表格行数据
cb.utils.alert("第"+currentRowPage+"行没有选择物料");
return;
}
//当前存储数据的数组下标
let currentBottom = i>=pageSize?parseInt(i/pageSize):0;
if ((i+1)%pageSize != 1 && rowAllDatas[i].wuliaobianma) {
productConditions = (productConditions + ", '" + rowAllDatas[i].wuliaobianma + "'");
} else if (rowAllDatas[i].wuliaobianma) {
productConditions = (productConditions + "'" + rowAllDatas[i].wuliaobianma + "'");
}
productConditionsArr.push(rowAllDatas[i]);//将数据添加到条件数组中
if(((i+1)%pageSize==0&¤tBottom<Math.ceil(rowSize/pageSize))||i==rowSize-1){
////定义两个键值对,condition:存储条件字符串,arr:存储生成条件的数组
arrData[currentBottom]={"condition":productConditions,"arr":productConditionsArr};
productConditions="";
productConditionsArr=[];
}
}
//调用后端函数
for(let i=0;i<arrData.length;i++){
//使用同步的方式调用api函数
let result = cb.rest.invokeFunction("GT9640AT12.api.queryYjByWlbm01", {kehufenlei: kehufenlei, _productConditions: arrData[i].condition},
function(err, res) {},viewModel, {async:false});
if (result.error != undefined) {
cb.utils.alert("请先选择促销地点编码!");
return;
}
let currentResPageCondition = arrData[i].arr; //生成当前返回数据的数组
let resultResponse = result.result.res; //响应结果
//根据返回结果做匹配赋值处理
for (let x = 0; x < currentResPageCondition.length; x++) {
//拼装key值
let resultKey = kehufenlei+currentResPageCondition[x].wuliaobianma;
if(resultResponse.hasOwnProperty(resultKey)){
let useProductInfo = resultResponse[resultKey]; //当前行要使用的物料信息
let baseIndex = i==0?0:i*pageSize; //每次分页初始编号
let rowNo = x+baseIndex;//行号
gridModel.setCellValue(rowNo, "yuanjia", useProductInfo.price);//赋值
}
}
}
});
//后端api函数查询yonql
let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
let kehufenlei = request.kehufenlei;
let productConditions = request._productConditions;
let sql = "select price,b.productId productId from marketing.price.PriceRecord inner join marketing.price.PriceRecordDimension b on id = b.priceRecordId where enable = '1'";
sql += " and b.productId in (" + productConditions + ") and b.agentClassId = '" + kehufenlei + "'";
let res = ObjectStore.queryByYonQL(sql, "marketingbill");//设置查询域
//组装对象,key为拼接的唯一标识,value为yonql查询返回的json数据
let resMap = {};
for (let i = 0; i < res.length; i++) {
resMap[kehufenlei+res[i].productId]=res[i];
}
return {res:resMap};
}
}
exports({"entryPoint":MyAPIHandler});
3.实现效果图
1.3注意点:
1.子表的列操作,当同时给某一列复制几百条数据时,可能会出现卡顿,需要找岳明老师开下优化开关。特殊注意下打开此开关会导致子表的公式失效。 打开子表优化开关,虽然子表的公式计算失效了,但是主表的公式还是可以使用的。
2.当子表通过脚本改变某列的值时,不会触发主表中用该列计算的公式,只有手动改变该列的值,才会触发。