跳转至

title: 泛微 E9 前端开发速查表 (JS/CheatSheet) created: 2026-04-21 updated: 2026-04-21 type: reference tags: [weaver, e9, js, wfform, ecode, dev] related: [oa/ecode-guide.md, oa/development-standards.md]


泛微 E9 前端开发速查表

本文档汇总了泛微 E9 流程表单开发中常用的 WfForm API、常见场景代码模板及最佳实践。适用于 Ecode 开发与表单自定义 JS 代码块。

1. 核心基础

1.1 环境准备与对象获取

E9 表单中,所有操作均基于 WfForm 对象。

jQuery(document).ready(function() {
    // 获取 WfForm 对象(兼容 Ecode 和传统代码块)
    const form = window.WfForm || window.parent.WfForm;

    // 获取表单基础信息(节点ID、请求ID、workflowId 等)
    // const baseInfo = WfForm.getBaseInfo(); 
});

1.2 最佳实践红线

  1. 严禁直接操作 DOM:如 document.getElementByIdjQuery('#fieldxxx') 获取值。必须使用 WfForm API,否则在 E9 新版表单引擎或 Ecode 模式下可能失效。
  2. 变量声明:严禁使用 var。优先使用 const(即便在回调中,也是独立快照),仅在需要重新赋值时使用 let
  3. ID 动态映射:使用 WfForm.convertFieldNameToId('name', 'detail_x') 获取真实 Field ID,避免硬编码 field123

2. 常用 API 速查

2.1 主表字段操作

// 获取字段值 (返回字符串)
const value = form.getFieldValue('field1234');

// 设置字段值
form.setFieldValue('field1234', 'New Value');

// 绑定字段值变化事件
// id 是字段ID,value 是新值
form.bindFieldChangeEvent('field1234', function(obj, id, value){
    console.log('字段值变为:', value);
});
indFieldChangeEvent('field1234', function(obj, id, value){ console.log('字段值变为:', value); }); ``### 2.2 明细表操作 (Detail Table) 明细表字段 ID 格式通常为fieldID_rowIndex(如field1234_0`)。

// 获取明细表所有行索引字符串 (例如 "0,1,2")
// 注意:空行时可能返回 ""
const rowStr = form.getDetailAllRowIndexStr('detail_1'); 
const rows = rowStr ? rowStr.split(',') : [];

// 遍历明细表
rows.forEach(rowIndex => {
    const val = form.getFieldValue(`field1234_${rowIndex}`);
    // do something...
});

// 绑定明细字段变化事件
form.bindDetailFieldChangeEvent('field1234', function(id, rowIndex, value) {
    console.log(`明细表行 ${rowIndex} 的值变为: ${value}`);
});

2.3 字段显示/隐藏与必填控制

// 显示字段
form.showField('field1234');

// 隐藏字段 (自动取消必填)
form.hideField('field1234');

// 设置/取消必填标记 (红星)
// 注意:仅设置 UI 标记,不改变后端校验配置。
form.setFieldRequiredMark('field1234', true);
form.setFieldRequiredMark('field1234', false);

2.4 常用工具函数

// 日期范围控制 (endDate >= startDate)
// 字段 change 时触发
WfForm.controlDateRange('startDateField', 'endDateField');

// 浏览按钮过滤条件
// 过滤出部门 ID 为 123 的人员
form.setBrowserCondition('hrmField', "departmentid='123'");

3. 高频场景代码模板

部门 ID 为 123 的人员 form.setBrowserCondition('hrmField', "departmentid='123'");

---

## 3. 高频场景代码模板### 3.1 场景:字段联动(显示/隐藏 + 必填联动)
**需求**:当字段 A 选择"是"时,显示字段 B 并设为必填;否则隐藏并清空。

```javascript
jQuery(document).ready(function() {
    const FIELD_A = 'field100'; // 触发字段
    const FIELD_B = 'field101'; // 目标字段
    const form = window.WfForm;

    function toggleField() {
        const valA = form.getFieldValue(FIELD_A);

        if (valA === '1') { // 假设 '1' 代表是
            form.showField(FIELD_B);
            form.setFieldRequiredMark(FIELD_B, true);
        } else {
            form.hideField(FIELD_B);
            form.setFieldRequiredMark(FIELD_B, false);
            form.setFieldValue(FIELD_B, ''); // 隐藏时清空值,防止提交校验报错
        }
    }

    // 绑定变化事件
    form.bindFieldChangeEvent(FIELD_A, function(obj, id, value){
        toggleField();
    });

    // 页面加载初始化 (使用 setTimeout 防止表单未加载完)
    setTimeout(toggleField, 500);
});
eField(); });

// 页面加载初始化 (使用 setTimeout 防止表单未加载完)
setTimeout(toggleField, 500);

}); ```### 3.2 场景:明细表数据校验(提交拦截) 需求:提交时检查明细表中字段 A 不能为空。

jQuery(document).ready(function() {
    const form = window.WfForm;
    const FIELD_A = 'field200';

    // 注册提交前检查事件 (支持保存、提交、提交确认)
    form.registerCheckEvent(WfForm.OPER_SAVE + ',' + WfForm.OPER_SUBMIT, function(callback){
        let errorMsg = '';
        const rows = form.getDetailAllRowIndexStr('detail_1').split(',');

        for (let i = 0; i < rows.length; i++) {
            const row = rows[i];
            const val = form.getFieldValue(`${FIELD_A}_${row}`);
            if (!val || val.trim() === '') {
                errorMsg += `第 ${parseInt(row)+1} 行 [字段A] 不能为空。\n`;
            }
        }

        if (errorMsg) {
            WfForm.showConfirm(errorMsg, function(){ /* 点击确定后无操作 */ });
            return; // 阻断提交
        }

        callback(); // 校验通过,继续提交流程
    });
});
); return; // 阻断提交 }

    callback(); // 校验通过,继续提交流程
});

}); ```### 3.3 场景:明细表数值汇总到主表 需求:明细表金额变化时,自动汇总到主表“总金额”。

jQuery(document).ready(function() {
    const form = window.WfForm;
    const DETAIL_FIELD = 'field300'; // 明细金额
    const MAIN_TOTAL   = 'field301'; // 主表总额
    const DETAIL_TABLE = 'detail_1';

    function calcTotal() {
        let sum = 0;
        const rows = form.getDetailAllRowIndexStr(DETAIL_TABLE).split(',');
        rows.forEach(idx => {
            let val = parseFloat(form.getFieldValue(`${DETAIL_FIELD}_${idx}`));
            if (!isNaN(val)) sum += val;
        });
        form.setFieldValue(MAIN_TOTAL, sum.toFixed(2));
    }

    // 绑定明细字段变化
    form.bindDetailFieldChangeEvent(DETAIL_FIELD, calcTotal);

    // 绑定明细行增删事件
    form.bindFieldAction('click', `addDetail${DETAIL_TABLE}`, calcTotal);
    form.bindFieldAction('click', `delDetail${DETAIL_TABLE}`, calcTotal); // 需确认删除按钮ID格式
});

4. 避坑指南

坑点现象 原因分析 解决方案
WfForm is not defined 脚本在 WfForm 加载前执行 放在 jQuery(document).ready 中;Ecode 中使用 onRendersetInterval 轮询直到 WfForm 存在。
隐藏字段后提交报错 字段设为必填,隐藏后清空了值 隐藏时务必调用 form.setFieldRequiredMark(id, false) 取消必填。
明细表取值 undefined 索引拼接错误 确保格式为 fieldID + '_' + rowIndex。注意 rowIndex 是从 0 开始的字符串。
bindFieldChangeEvent 不触发 字段 ID 错误或被覆盖 检查字段是否被其他脚本覆盖;确认 ID 是后端真实 ID 而非 Name。