使用JavaScript面向对象编程展现报表数据

在关系型数据库中,普通报表数据一般是按行存储。通常情况下做报表展现开发,需依赖关系型数据库,循环处理每行数据,在客户端界面展现。这样的需求一般可以使用报表控件或写点JavaScript代码就能解决。
如今,有些报表或表单,以文档的形式存储在非关系型数据库中,例如使用MongoDB数据库存储,本文的“安全生产管理”业务案例就使用了MongoDB数据库,如下图举例所示的“安全生产管理检查”表。

这里写图片描述
基于上述需求设计开发过程中,我对JavaScript编程语言的认识逐渐提高,摒弃了简单脚本语言看法,把早年写C++、Java代码的面向对象设计开发的感觉联系上了。由于本人近年很少写代码,对JavaScript语言掌握初浅,分享面向对象使用体会,方便学习交流。
JavaScript 语言是通过一种叫做 原型(prototype)的方式来实现面向对象编程的。 本文不探讨面向对象的形式和方法,只是分享一种使用方式。

回到上图安全生产管理检查表需求,以检查表序号为1的行数据为例,JSON数据转换到展现表格上对应关系如下图所示。
这里写图片描述
这一行数据,可以看成数据结构中的一棵树,遍历树得到如图所示的表格。按面向对象方式,定义此行数据为一个对象,命名为:RowData,此对象内含rowspan及多个检查数据对象(命名为:InspectData),每个InspectData对象,内含其rowspan及多行隐患检查数据对象。

定义上述对象示例代码如下所示:

//定义报表展现数据MongoDB Scheme
function InspectSchemeKey(){
    this._contents;
    this._troublesitem;
    this._notroubles;
    this._troubles;
    this._score;
    this.init = function (contents,troublesitem,notroubles,troubles,score){
        this._contents = contents;
        this._troublesitem = troublesitem;
        this._notroubles = notroubles;
        this._troubles = troubles;
        this._score = score;
    };
}

//定义检查依据,检查隐患及数据
function InspectData(subJSONobj,basiskey){
    this._basis;
    this._rowspan = getJSONRowNum(subJSONobj);
    this.inspects = [];
    this.init = function (subJSONobj,basiskey,schemekey) {
        this._basis = subJSONobj[basiskey];
        tmp = subJSONobj[schemekey._contents];

        for (var j = 0; j<this._rowspan; j++ ){
            this.inspects[j] = "<td>" + tmp[j][schemekey._troublesitem] + "</td>" + "<td>" + tmp[j][schemekey._score]  + "</td>";
        }
    };
}

//自定义一行数据对象(含纵向合并单元格rowspan)
function RowData(seq,JSONObj){
    this.seq = seq;
    this.inspectitem;
    this.inspects = [];
    this.rowspan = getJSONRowNum(JSONObj);
    this.init = function(JSONObj){
        SchemeKey = new InspectSchemeKey();

        SchemeKey.init("contentd","fieldtype","ok","detail","fieldcode");

        this.inspectitem = JSONObj["title"];
        //for(var tmp_obj in JSONObj){
            var tmp_obj = "subtable" ;
            if (typeof(JSONObj[tmp_obj])=="object"){
                //判断运算符是否定义
                if( typeof(JSONObj[tmp_obj].length) != "undefined" ){
                    var n = JSONObj[tmp_obj].length;
                    var tmp = JSONObj[tmp_obj];
                    for (var i = 0;i < n; i++) {
                        //fieldid定义检查依据
                        this.inspects[i] = new InspectData(tmp[i],"fieldid");
                        this.inspects[i].init(tmp[i],"fieldid",SchemeKey);
                    }
                }
            }
        //}     
    };

}

注:函数getJSONRowNum( )源码见博文《使用JavaScript编程分析多级嵌套JSON文档数据

完成上述代码后,发现没有返回报表中整行数据对象的HTML字符串,为此,使用prototype为RowData对象添加新方法getHtml,用以返回可展现的HTML,整合验证代码如下:

//获取展现HTML(扩展RowData对象方法,定义在原型中)
RowData.prototype.getHtml = function () {
    var htmlstr = "<tr>" ;

    htmlstr = htmlstr + "<td rowspan=";
    htmlstr = htmlstr + this.rowspan + ">"
    htmlstr = htmlstr + this.inspectitem + "</td>" ;    
    for (var k=0; k < this.inspects.length ; k++ ) {
        if (k > 0 )
            htmlstr = htmlstr + "<tr>";

        htmlstr = htmlstr + "<td rowspan=";
        htmlstr = htmlstr + this.inspects[k]._rowspan + ">"
        htmlstr = htmlstr + this.inspects[k]._basis + "</td>" ;
        for (var li=0; li < this.inspects[k].inspects.length ; li++){
            if (li > 0 )
                htmlstr = htmlstr + "<tr>";
            htmlstr = htmlstr + this.inspects[k].inspects[li];  
            htmlstr = htmlstr + "</tr>";
        }
    }
    return htmlstr;
}

//验证模拟数据,alert出html。
function showAllElem(){
    var jsons = "";  //定义返回JSON数据字符串

    jsons = "{\"name\":\"安全生产检查\",\"title\":\"安全生产组织保障\",";
    jsons = jsons + "\"subtable\":[{\"fieldid\":\"机房安全防火\",\"contentd\":[{\"fieldtype\":\"电源\",\"fieldcode\":\"分值\"}";
    jsons = jsons + ",{\"fieldtype\":\"计算机\",\"fieldcode\":\"分值\"}";
    jsons = jsons + ",{\"fieldtype\":\"空调\",\"fieldcode\":\"分值\"}";
    jsons = jsons + ",{\"fieldtype\":\"电视\",\"fieldcode\":\"分值\"}]}";
    jsons = jsons + ",{\"fieldid\":\"车辆安全\",\"contentd\":[{\"fieldtype\":\"年限\",\"fieldcode\":\"分值\"}";
    jsons = jsons + ",{\"fieldtype\":\"保险\",\"fieldcode\":\"分值\"}]}";
    jsons = jsons + ",{\"fieldid\":\"其他安全\",\"contentd\":[{\"fieldtype\":\"年限\",\"fieldcode\":\"分值\"}]}]";
    jsons = jsons + ",\"field\":\"等分\"}";   

    //将 JavaScript 对象表示法 (JSON) 字符串转换为对象。
    json_obj = JSON.parse(jsons);

    var strtmp = new String("对象:");

    var myRowdata = new RowData(1,json_obj);
    myRowdata.init(json_obj);   
    strtmp = strtmp + myRowdata.getHtml();  
    alert(strtmp);
}

把showAllElem()函数加载到button上,如下代码所示“测试展示表单数据”。

<button id="test" type="button" onclick="showAllElem()">测试展示表单数据</button>

把返回字符串,嵌入如下HTML文档中:

<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head></head>
<body>
<table width="713" height="318" border="1" cellpadding="0" cellspacing="0">
//这里写返回HTML字符片
</table>
</body>
</html>

把执行showAllElem函数所返回html字符串截取放入上文HTML文档中,显示效果如下:
这里写图片描述

小结:使用JavaScript面向对象编程,思路清晰,代码简洁。特别是prototype的使用,为对象动态添加方法的方法,很灵活。不过,在调试程序过程中,发现自定义嵌套对象中的重名变量,如果未使用var定义,将成为全局的变量,稍后将深入学习闭包的知识。

由于作者水平有限,存在不足之处,欢迎反馈交流。

参考:

全面理解面向对象的 JavaScript》曾滢著 2013.4
文档型信息交互设计及相关技术实现》肖永威 2015.6
嵌套JSON数据自动回写HTML网页》 肖永威 2015.5

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肖永威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值