Method 开发指南
当可视化的低代码配置无法满足业务流程中的逻辑计算、动作校验或系统对接时,开发者可以通过编写 Method(方法)实现深度扩展。
Aras 支持运行在两个不同端的方法:
- 客户端方法(Client Method):使用 JavaScript 编写,在用户的 Web 浏览器中运行
- 服务端方法(Server Method):使用 C# 编写,在 IIS 服务端运行,具备完整的数据库事务控制权限
客户端 JavaScript 方法
客户端方法常用于拦截表单操作、在页面加载时调整控件布局,或根据用户输入联动修改其他字段的值。
常用绑定事件
| 事件类型 | 事件名 | 触发时机 |
|---|---|---|
| Form Event | OnLoad | 表单加载完成时 |
| Form Event | OnBeforeSave | 表单保存前 |
| Field Event | OnChange | 字段值变更时 |
| Field Event | OnBlur | 字段失去焦点时 |
代码示例:自动计算总价
以下示例演示在表单中根据"数量"和"单价"的变化自动计算"总价":
javascript
// document.thisItem 代表客户端当前的 Item 数据节点对象
var thisItem = document.thisItem;
// 获取字段值,getProperty 支持指定默认值
var qtyStr = thisItem.getProperty("quantity", "0");
var priceStr = thisItem.getProperty("unit_price", "0");
var qty = parseInt(qtyStr, 10);
var price = parseFloat(priceStr);
if (isNaN(qty) || isNaN(price) || qty < 0 || price < 0) {
// 使用全局 aras 对象弹出标准错误提示框
aras.AlertError("输入的数量或单价格式不正确");
return false;
}
var total = qty * price;
// 使用 handleItemChange 填回字段值,确保触发脏数据标记和表单联动
handleItemChange("total_amount", total.toString());
return this;服务端 C# 方法
服务端方法是 Aras 核心二次开发的重点。这类方法通常挂载在 ItemType 的 Server Events 上,处于 SQL 数据库底层事务中。
事务生命周期事件
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
| OnBeforeAdd | 写入数据库前 | 验证数据合法性、自动生成编号 |
| OnAfterAdd | 写入数据库并提交后 | 发送通知邮件、同步外部 ERP 数据 |
| OnBeforeUpdate | 更新数据库前 | 字段校验、联动计算 |
| OnAfterUpdate | 更新数据库并提交后 | 触发下游流程 |
| OnBeforeDelete | 物理删除前 | 级联清理检查 |
| OnAfterDelete | 物理删除后 | 日志记录 |
`this` 关键字的含义
在 Server Method 中,this 直接代表当前请求传递的 Item 节点,可直接调用 getProperty()、getRelationships() 等方法。
代码示例:采购申请单校验
在保存采购申请单(Requisition)前拦截,校验明细行是否包含物料:
csharp
Innovator inn = this.getInnovator();
string reqNumber = this.getProperty("req_number", "");
// 获取申请单关联的关系类列表(子网格数据)
Item details = this.getRelationships("Requisition_Detail");
int detailCount = details.getItemCount();
if (detailCount <= 0)
{
// 返回 newError 会自动中止当前事务,防止脏数据入库
return inn.newError($"采购申请单 [{reqNumber}] 保存失败:必须包含至少一条采购明细数据!");
}
// 遍历明细行,逐行校验单价
for (int i = 0; i < detailCount; i++)
{
Item row = details.getItemByIndex(i);
string priceStr = row.getProperty("price", "0");
double price = Convert.ToDouble(priceStr);
if (price <= 0)
{
return inn.newError($"第 {i + 1} 行明细单价必须大于 0!");
}
}
// 返回 this 说明校验通过,允许事务继续提交
return this;AML 快速参考
AML(Aras Markup Language)是 Innovator 的专有 XML 命令格式,所有数据交互都通过 AML 传递。完整的 AML 语法详见 AML 查询 章节。
基本查询结构
xml
<!-- 查询编号为 P-10023 的零件,仅返回 item_number 和 name -->
<Item type="Part" action="get" select="item_number,name">
<item_number>P-10023</item_number>
</Item>使用 IOM 构建 AML
在 Server Method 中,通过 IOM 链式调用生成 AML,比手动拼接 XML 更安全:
csharp
Innovator inn = this.getInnovator();
Item partQuery = inn.newItem("Part", "get");
partQuery.setAttribute("select", "item_number,name");
partQuery.setProperty("item_number", "P-10023");
Item result = partQuery.apply();
if (result.isError())
{
return inn.newError($"未找到对应的零件:{result.getErrorDetail()}");
}
string partName = result.getProperty("name");
return inn.newResult($"成功获取零件信息,名称为: {partName}");