掌握事件前后台响应机制

开发带人机交互界面的业务系统,一定离不开对事件的捕获和响应,以完成相关前台和后台业务逻辑。与一般的 Web DOM 级事件不同,Enhancer 对事件的捕获和响应做了抽象和精简, 事件粒度是业务级的。本小节将介绍 Enhancer 的事件机制。

1. 事件的触发和响应配置详解

页面中的事件可以由窗口触发,也可以由附着在窗口上的按钮组件触发。在流程图中,右键点击窗口,在事件菜单中可以看到该窗口(含组件和按钮)当前所能触发的事件列表。点击具体的事件名,则可以打开对该事件响应的设置面板如下图:

Enhancer 事件响应的过程会按照上图配置顺序从上到下,按照勾选状态来做,具体含义解释如下:

  1. 检查窗口

    勾选后会触发窗口内部的校验逻辑,具体校验的形式取决于窗口盛放的不同组件。比如表单会检查每个输入域的合法性,查询列表会检查用户当前是否选中了某行。校验不通过时,后续动作不会执行。开发者可以根据不同的业务场景需要,设置校验不通过时的提示信息。

  2. 执行前询问

    勾选后,可以根据具体的业务逻辑,设置询问内容比如 您确定要删除吗?。在事件触发时,页面会弹出包含询问内容的确认框,等待用户选则是否要继续执行。

  3. 执行事件触发时脚本

    勾选后,可以设置一段包含变量的 JavaScipt 脚本,该脚本执行之后,如果返回 false,则不会往后面执行。

  4. 执行服务器过程

    勾选后,可以设置 要执行的后台 SQL 或者后台 JavaScript 脚本,来完成具体的业务逻辑持久化操作。具体的服务器过程设置规则参考本小节 第 2 段。

  5. 执行动作执行前脚本

    勾选后,可以设置动作执行(动作线)前需要执行的 JavaScript 脚本。如果返回 false,则不会执行后续动作。

  6. 附加影响

    勾选后,可以设置是否要在完成事件响应之后重置页面,帧或者影响窗口。

  7. 执行动作执行后脚本

    勾选后,可以设置动作执行后需要执行的 JavaScript 脚本。

2. 如何正确地设置服务器过程

2.1 执行 SQL

  • 单条 SQL

直接书写带变量的 SQL,如:

INSERT INTO TAB_A(F1, F2, F3, ...)
    VALUES(@11-VAR1@, @11-VAR2@, @VAR3@)
  • 一次执行多条 SQL

可以使用 $1, $2, $3, ... 标识符依次来表示引用第 1 条, 第 2 条, 第 3 条 SQL... 执行的结果。如:

INSERT INTO tab_a(F1, F2, F3, ...)
    VALUES(@11-VAR1@, @11-VAR2@, @VAR3@)

UPDATE tab_b SET f1 = @12-VAR1@, f2 = @VAR2@
    WHERE id = $1.insertId; -- <-- $1.insertId 即 第一条 SQL 执行的结果。
  • SQL 中嵌入 JavaScript 脚本

可以使用 # JavaScript 脚本 # 嵌入 SQL 中对变量进行加工处理,如:

INSERT INTO tab_a(F1, F2, F3) VALUES(
    /* F1 */
    #@11-VAR1@ + '-' + @11-VAR2@#,
    /* F2 */
    #@12-NAMES@.split(',').map(function(s) {
        return s.replace(/\s/g, '');
    }).join(':')#,
    /* F3 */
    #var a = @12-VAR@;
     var b = @USER_ID@;
     a + b;
      #
);
  • 添加错误码对照提示

对于一些需要明确提示给用户的 SQL 错误,可以设置SQL 错误码对应的错误提示信息,以增加交互的友好性。比如给常见的主键重复错误码ER_DUP_KEY添加对照提示您添加的学号已经存在!

2.2 执行 JavaScript 过程【选修】

如果编写通用 SQL 的方式不能满足您的特殊业务需求,那么可以编写原生后台 JavaScript 过程,控制整个执行过程。后台可供使用的 API 参考API-Server.md

  • 通用示例
var sql = `UPDATE student SET name = ?
    , birthday = ?, birth_place = ?
    , gender = ?, phone = ?
    , nation = ?, entry_year = ?
    , ssn = ?, family_address = ?
    , political_status = ?, school_year_length = ?
    WHERE student_no = ?`;

// 直接 @变量@ 从页面取用本次过程执行需要的数据。
var params = [
    @12-NAME@, @12-BIRTHDAY@, @12-BIRTH_PLACE@
    , @12-GENDER@, @12-PHONE@, @12-NATION@, @12-ENTRY_YEAR@
    , @12-SSN@, @12-FAMILY_ADDRESS@, @12-POLITICAL_STATUS@
    , @12-SCHOOL_YEAR_LENGTH@, @12-STUDENT_NO@
];

// Enhancer 是全局对象,直接使用。
var databaseService = Enhancer.getDatabaseService();  

// 执行 SQL
databaseService.execute(sql, params, function(err, result) {
    if (err) {
        // 不论结果执行成功失败,需要调用 done 方法表示本次过程结束。
        // done 方法的第一个参数传递系统级 err,第二个参数传递常规结
        // 果对象(包含 success 和 message 字段)。
        done(null, {
            success: false,
            message: '操作失败操作失败。' + err.message
        });
        return;
    }
    done(null, {
        success: true,
        message: '修改成功!'
    });
});
// 注意:执行 SQL 的数据库连接的获取和释放由内部统一控制,用户无需关心。
// 如果需要做事务,可以调用 databaseService.beginTransaction 方法,
// 请参考: https://assets.enhancer.io/enhancer/tutorials/0.1.9/zh-cn/api-server.html

2.3 执行提交前前端脚本(可选)

本前端脚本的设置可以满足以下需求:

  • 如果您想在过程提交到后台执行前,做一些条件判断,来决定是否要提交,则直接在脚本中返回 false 即可阻止本次提交,如:
if (/** 条件不满足 **/) {
    return false;
}
  • 如果想改变提交的参数变量的值,可以直接返回包含新变量值的 JSON,对即将提交到后台的变量值做覆盖,如:
var amount = @11-amount@ + @11-total@ + 3;
var rows = @11-rows@.map(function(s) {
    return s.split('-')[0];
});

return {
    "11-amount": amount,
    "11-rows": rows,
    "12-other": "something"
};

2.4 执行 SQL 执行前后台脚本(可选)

此脚本仅当过程类型选择为 SQL 时才能设置。可以满足以下需求:

  • SQL 执行前需要对参数做后台校验。
  • SQL 执行前需要改变或者新增参数。

例:

if (!@11-PHONE@) {
    // 校验不合法则调用 done 方法,并设置 sucess 参数为 false。
    done(null, {
        success: false,
        message: '电话号码必填'
    });
    return;
}
// 可以根据情况再做一次 IO 来深度校验某些参数,然后调用 done() 方法。
// var dbService = Enhancer.getDatabaseService(); 
// ...

// 可以在 SQL 执行前再次改变参数的值。
parameters['11-PHONE'] = '86' + @11-PHONE@;

// 一定要调用 done 方法,这样才能继续执行后续程序。
done();

注意:一定要调用 done 方法,程序才能继续执行

使用 Enhancer 事件动作响应处理机制,结合 Enhancer 变量体系,可以使得业务逻辑的开发变得更直观和高效。

Demo

results matching ""

    No results matching ""