TableTemplet 状态栏表格模版(注释版)

Author: 小小梦, Created: 2017-06-22 23:00:04, Updated: 2017-10-11 10:39:48

TableTemplet 状态栏表格模版(注释版)

感谢平台用户 ID :职业养鸡户 共享该模版: 该模版使用比较简单,每个函数的作用都有说明,在开发策略的时候可以更好的架构策略,分离出显示界面。 提取、修改、更新状态栏数据也变得比较容易,非常方便,而且代码量很小,也比较适合扩展。

有兴趣的用户可以学习一下源码,这里逐行翻译了一下。 方便了解这个模版的运行细节。 main 函数 测试部分 可以复制到单独的策略,然后引用该模版测试。 如有BUG 或者 建议 欢迎留言 ^^

/*
作者: ID  养鸡专业户
翻译: littleDream
*/

var listener = Array(); // 声明一个 全局变量 并且初始化为空数组对象, 用来储存 按钮(button)响应的 函数引用。

// 用于构造 按键 对象的函数
TableButton = function(cmd, name, callback) {    // cmd : 用于 GetCommand 捕获的 命令 , name : 按键显示的名称   修改:增加  callback
    var self = {}               // 构造一个 空对象
    self.type = "button";       // 给构造的对象 添加 属性 type  并 赋值   "button"  , 参见 API 文档  LogStatus 函数,和论坛帖子“策略状态栏中构造交互按钮功能”
    self.cmd = cmd;             // 添加 cmd 属性 并用参数  cmd 赋值
    self.name = name;           // 添加 name 属性
    // 下行新增
    listener[cmd] = callback;   // 给对应的 命令通过 键--键值 绑定 对应的回调函数
    
    return self;                // 返回构造好的对象
}

// 模版导出函数, 用于设置 表格信息,返回一个对象可以调用 该对象的成员函数压入 数据
$.TableInfo = function() {
    var self = {}                                            // 构造一个 空对象
    self.cols = [];                                          // 给构造的空对象 添加属性 cols 并赋值 一个 空数组
    self.rows = [];                                          // 给构造的空对象 添加属性 rows 并赋值 一个 空数组
    self.pushBtn = function(col, cmd, name, callback) {      // 添加 属性 pushBtn 引用一个 匿名函数, 参数为 列名、捕获的命令、按钮名称、回调函数(按钮最终触发的函数)
        /* var btn = TableButton(cmd, name) */
        self.cols.push(col)                                  // 向列 压入数据 显示为列名
        self.rows.push({                                     // 压入  按钮的 格式(JSON)
            'type': 'button',                                // 类型设置 为 按钮
            'cmd': cmd,                                      // 触发的 命令
            'name': name                                     // 按钮上显示的名称
        })
        listener[cmd] = callback;                            // 给对应的 命令通过 键--键值 绑定 对应的回调函数
    }
    self.push = function(col, row) {                         // 压入 普通数据 参数 : col 列名,   row : 行上的值
        self.cols.push(col)                                  // 压入 数组 操作
        self.rows.push(row)                                  // 压入 数组 操作
    }
    return self;                                             // 返回构造的对象
}

// 构造 table  表格对象,  createTable 表格对象的构造函数
function createTable() {
    var self = {}                                             // 声明一个 空对象
    self.type = "table"                                       // 添加属性 type , 用 “table” 赋值, 定义表格类型用于在状态栏显示 出表格,参见API文档 LogStatus 函数
    self.title = "持仓信息"                                    // 表格显示的 分页标题 默认 为 “持仓信息”
    self.cols = []                                            // 用以储存表格的列名
    self.rows = []                                            // 用以储存表格的行数据
    
    // 声明的空对象添加成员函数
    self.SetRowByTableInfo = function(index, argument) {      // 根据 导出函数 $.TableInfo  返回的对象 去设置 表格的 row 行数据,参数是: 行号,$.TableInfo的返回值
        if (argument.cols != null)                            // 传入的参数  argument.cols 不等于 null 
            self.cols = argument.cols;                        // 替换掉 列名
        self.rows[index] = argument.rows;                     // 替换掉 指定 行数 index 的行数据 rows 
    }

    self.SetRow = function(index, rowself) {                  // 设置行数据,直接设置, 参数 设置的行 index , 要设置的数据rowself
        while (self.rows.length < index)                      // 如果超出 先添加 空白行  , 应该是 -1    if 修改为 while , 添加之间的空行。
            self.rows.push(Array(rowself.length))             // self.push("") 修改
        self.rows[index] = rowself                            // 参数 传入的行数据  rowself 赋值给 表格数组中 指定的行的索引位置
    }

    self.SetRowCount = function(count) {                      // 设置行数, 传入的参数就是 需要设置的 行数。
        // 增加代码
        var lengthOfcols = self.cols.length;
        
        while (self.rows.length < count) {                    // 这里使用一个循环 来 把当前 不足的行数 补充一下。
            self.rows.push(Array(lengthOfcols));              // 只要当前的行数 即:self.rows.length 小于 参数 count , 就向  self.rows   push   空 "" 
        }
        if (self.rows.length > count) {                       // 如果 参数  count 小于当前的 已有行数。
            self.rows.splice(count, self.rows.length - count) // 调用数组的 元素删除函数 splice 删除 索引count 开始 (self.rows.length - count) 个 元素,即:删除 多于的元素。
        }
    }

    self.GetRow = function(index) {                           // 获取 指定行数的 表格行数据。
        return self.rows[index]
    }

    self.Init = function(title/*, cols, rows*/) {             // 初始化表格 , 参数 :  分页标题
        self.title = title;                                   // 表格 对象的 title  属性  设置为 参数传入的 字符串
        /*作者删除
        if (cols != null)                                     // 如果传入的 cols 不为 null, 把参数cols 赋值给 表格对象的 cols 属性
            self.cols = cols;
        if (rows != null) {                                   // 如果传入的 rows 不为 null, 对 参数 rows 遍历处理,压入编号
                                                              // 此处应该有一个判断 rows 是否是数组。
            for (var i = 0; i < rows.length; i++) {           // 遍历
                self.rows.push(rows[i]);                      // 修改 rows.push("r" + i)
            }
        }
        */
    }
    return self;                                              // 返回 表格对象
}

$.createTableMgr = function() {                               // 构造表格控制对象
    var self = {}                                             // 声明一个 空对象
    self.table = []                                           // 声明一个 空数组, table 感觉 tabls 贴切,  这个table 变量用来存放 表格对象,可以同时显示出多个表格。

    self.GetTable = function(index) {                         // 给表格控制对象添加 成员函数:  获取表格  GetTable  , 参数 index  指定获取 哪个表格。
        if (typeof(index) === 'number') {                     // 如果传入的 参数 index  为数值类型 , 返回索引为 index 的 self.table 数组的元素。
            return self.table[index]                          // 如果索引 index 输入 超出, 还是有可能返回 undefined
        } else {
            for (var i = 0; i < self.table.length; i++) {     // 如果传入的 参数 index 不是索引,而是 表格对象的 分页标题 字符串, 则遍历 self.table 数组 
                if (self.table[i].title == index)             // 对比每一个  表格对象的  分页标题,  找到相同的 分页标题 就返回该  表格对象。
                    return self.table[i]                      // 返回 表格对象
            }
        }
    }

    self.AddTable = function(title, cols, rows) {            // 把 表格对象  添加到 表格控制对象的 table 属性。  可以指定 表格的标题 ,列数据  , 行数据
        var tb = createTable();                              // 调用 createTable 函数 构造一个 表格对象 赋值给 tb                           
        tb.Init(title, cols, rows);                          // 调用 表格对象的 成员函数  初始化表格  传入参数 title, cols, rows

        self.table.push(tb)                                  // 把构造好的 表格对象压入 表格控制对象 的属性 table 数组中。
        return tb;                                           // 返回这个  添加 的表格对象。
    }
    
    /* 作者删除
    self.AddListener = function(key, value) {                // 添加 监听函数。
        self.listener[key] = value;                          // 此处测试。
    }
    */
    
    self.UpdateCMD = function() {                            // 检测按钮 触发 命令。
        var cmd = GetCommand()                               // 调用  API 函数  检测 交互有没有触发
        if (cmd) {                                           // 如果 cmd 接受到交互信息
            var cmdstr = cmd + "";                           // 用空字符串  加 cmd 做转换为字符串,  应该可以直接 用cmd
            if (!!listener[cmdstr]) {                        // !!listener[cmdstr] 表达式 返回 false 即 listener 中没有 cmdstr 为 键的值, 如果 为true 则是有值(即:cmdstr 命令对应的回调函数)
                listener[cmdstr](cmdstr);                    // 调用 该命令对应的回调函数 。
            } else {
                Log("找不到名为:" + cmdstr + "的命令")         // 否则 打印日志 :  找不到 命令
            }
        }
    }

    self.LogStatus = function(before, end) {                 // 表格控制对象 添加的 成员函数 LogStatus  (即 封装一下 API LogStatus)
        self.UpdateCMD();                                    // 检测交互命令 , 调用 表格控制对象的成员函数 UpdateCMD 。 如果有 按钮按下 ,就会触发相应 命令的 回调函数(在listener 中 Key-value形式储存)
        LogStatus(before + '\n`' + JSON.stringify(self.table) + '`\n' + end); // 支持多个表格同时显示, 将以TAB显示到一组里,    把参数 before ,end  添加在显示的表格 前、后,  调用API   LogStatus
                                                                              // 显示表格到状态栏。 要显示的表格都储存在 self.table 这个数组中, 详细的API 参见 文档: https://www.fmz.com/api 全局函数 LogStatus 函数
    }
    return self;
}

function main() {
    // 测试 表格控制对象
    var tb_manager = $.createTableMgr();
    var tb1 = tb_manager.AddTable("ceshi1");
    var tb2 = tb_manager.AddTable("ceshi2");
    var tb3 = tb_manager.AddTable("ceshi3");    
    tb_manager.LogStatus("up", "down");
    // 测试 GetTable 函数
    var obj_tb2 = tb_manager.GetTable("ceshi2");
    Log("obj_tb2:", obj_tb2);
    
    // 测试 $.TableInfo
    var info1 = $.TableInfo();
    for(var i = 0; i < 5; i++){
        info1.push("" + i, "a" + i);
    }
    tb1.SetRowByTableInfo(0, info1);
    
    // 测试 SetRow 函数
    tb1.SetRow(3, ["a", "b", "d"]);              // 超出已有索引 ,会再之前插入空行
    tb_manager.LogStatus("up", "down");
    
    // 测试 SetRowCount
    var info2 = $.TableInfo();
    info2.push("name", "Tom");
    info2.push("age", 12);
    tb2.SetRowByTableInfo(0, info2);
    tb2.SetRowCount(6);
    tb_manager.LogStatus("up", "down");
    // 测试GetRow
    var tb2_row = tb2.GetRow(0);
    Log("tb2_row:", tb2_row);
    
    // 测试 TableButton 
    var info3 = $.TableInfo();
    info3.push("按钮", TableButton("cover", "平仓", function(cmd){
        var time = new Date().getTime();
        Log(_D(time), "cmd:", cmd, "全平仓!#FF0000");
    }));
    tb3.SetRowByTableInfo(0, info3);
    tb_manager.LogStatus("up", "down");
    
    // 实盘测试 循环 避免程序 结束,  把  main 函数 复制到 单独的 策略中进行实际测试。
    while(true){
        // 测试 UpdateCMD
        var nowTime = new Date().getTime();
        tb_manager.UpdateCMD();
        tb_manager.LogStatus("time:" + _D(nowTime), "down");
        Sleep(1000);
    }
}

img


Related

More