在Apex的交互式网格如,如果您有许多可编辑的列,这些列决定了另一列的值,并且您希望所述列实时更新,甚至在单击“保存”之前也是如此。如果您过去曾有此要求,则可能会发现它不是一项简单的任务。
20.2版本以前,可以设置一种动态动作,该动作监听基本列的更改事件,然后通过“设置值”动作计算并将新值应用于目标列。当您有多个触发列时,这可能会有些棘手,需要在相关的每。我还发现这种方法很容易被人碰到,因为它似乎在不希望的时间触发,例如在单元格焦点上。它似乎对“设置值”操作的“初始化时触发”设置具有怪异的依赖关系,这似乎对是否this.data
填充将产生影响。
我过去采用的一种更可靠的方法是利用自定义onChange回调。这样可以进行更多控制,但仍然不必要地复杂。
但是,从APEX 20.2开始,已引入一种增强方法来实现此行为。它更简单,不需要创建额外的动态动作。满足calcValue和dependsOn。
作为模型的一部分,我们可以告诉一个字段有关其应更新的其他字段的更改,并提供一个计算并返回其新值的函数。从文档中还不清楚这些选项应该放在哪里,但是在检查了源代码之后,事实证明应该像下面这样使用它们:
// JavaScript Initialization Code of a specific column
function(options){
options.defaultGridColumnOptions = {
dependsOn: ['COL1', 'COL2', ...],
calcValue: function(argsArray, model, record){
return 'newValue';
}
};
return options;
}
对于更真实的示例,假设您有一列始终显示其他两列的总和。为了在页面加载以及导出之类的内容中显示正确的值,应在初始查询中重复相同的逻辑。在这里,我在名为SALCOMM的附加列中汇总了员工的薪水和佣金。
select empno
, ename
, job
, mgr
, hiredate
, deptno
, sal
, comm
, nvl(sal, 0) + nvl(comm, 0) as salcomm
from emp
我发现,不幸的是,新的calcValue方法仅适用于可编辑的列,即使在这种情况下,该列应为“仅显示”。为了解决这个问题,我将列类型设置为“文本字段”,但是我将CSS类添加is-readonly
到了列的“外观-> CSS类”属性中。我还将此列设置为“仅查询”。
以下是计算列属性设置截图:
在JavaScript方面,无论何时SAL或COMM列更改,我们都希望更新所述列,因此我们将dependsOn设置为['SAL', 'COMM']
。在calcValue函数中,我们可以从argsArray参数中获取当前的薪金和佣金值作为argsArray [0]和argsArray [1],或者使用更详细的模型参数。我还包括一些基本的输入检查。
function(options){
options.defaultGridColumnOptions = {
dependsOn: ['SAL', 'COMM'],
calcValue: function(argsArray, model, record){
const sal = parseFloat(model.getValue(record, 'SAL') || 0);
const comm = parseFloat(model.getValue(record, 'COMM') || 0);
if(isNaN(sal) || isNaN(comm)){
return 'error';
} else {
return sal + comm;
}
}
};
return options;
}
总的来说,我对这种新方法感到非常满意。逻辑很好地封装在column节点中,我们不必创建额外的Dynamic Action。