• 把JSON数据载入到页面表单的两种思路(对easyui自带方法进行改进)


    #把JSON数据载入到页面表单的两种思路(对easyui自带方法进行改进)
    
    ##背景
    项目中经常需要把JSON数据填充到页面表单,一开始我使用easyui自带的form load方法,觉得效率很低,经常在载入数据的时候有假死现象(实际项目中的表单一般都100-200个字段以上),而且不能处理radio/checkbox的情况。(easyui的思路是把它们都用combo去处理)
    
    ##思路
    问题可以转化为,现在有一堆JSON数据,有一个表单,可能是一一对应的,要把这个数据填写到表单上,一般说来有两种思路
    
    1. `方案一`针对数据,一个个选择元素进行填充
    2. `方案二`先选择所有的元素,再针对数据进行填充
    
    到底哪种比较优呢?
    
    ##测试验证
    可能也有人大概想到较优方案,但是对于实事求是的我,还是要写些代码去测试验证
    
    [我的测试例子](http://p2227.github.io/demo/loadForm/)
    
    效果截图:
    
    ![效果截图](https://images0.cnblogs.com/blog/84053/201402/032334565497675.jpg)
    
    ##结果
    `方案二`的思路明显要比`方案一`的优,而且查看原代码后发现,easyui自带的form load方案是以`方案一`为基准去处理的,再加上一些细节的处理,效率非常的慢.
    
    ##改进
    实际上我们还要处理radio/checkbox的情况,以及处理其他一些细节,故最后整理封装的代码如下
    ```javascript
    !function($){
        $.fn.extend({
            /*
              把JSON数据填充进表单,兼容easyui渲染过的表单
            * 20140203 reconstructed by p2227
            * 参数:
            * relateTable:关系表,key-value对象,即JSON数据与表单有不对应时的另外对照表
            * data:要填充的JSON数据
            * callBack:填充完数据后的回调函数,一般说来填充完数据要进行表单验证
            *
            * 用法:
            * $('form').loadForm({data:{key,value}});
            * */
            loadForm:function(conf){
                conf = conf || {};
                conf.relateTable = conf.relateTable || {};
    
                var rt = conf.relateTable;
                var formObj = this;
                var jsonData = conf.data;
                var newData = {};
                function fill1EasyUI(dom,data1){ //填充值到一个easyUI表单对象上
                    //目测针对combobox和datebox,其他表单对象 建议调用 easyUI本身的 form.load方法
                    var eDom = $("[comboName='" + dom.name + "']",formObj); //找到easyUI起作用的dom元素(不带name)
                    if(eDom.length<=0) return;
    
                    var type = eDom[0].className.match(/(w*?)-f/); //该dom的类上第一个带 "任意字母-f"的类
                    if(type && type.length>0){
                        type = type[1];
                        if(/datebox/i.test(type)){
                            data1 = flitDate(data1);
                        }
                        if (eDom[type]("options").multiple){
                            eDom[type]("setValues", data1.replace(/s*,s*/g,",").split(","));
                        } else {
                            eDom[type]("setValue", data1);
                        }
                    }else{
                        if(eDom.next("span.datebox").length>0){ //for IE7 IE6
                            eDom.datebox("setValue", flitDate(data1));
                        }
                    }
                }
    
                /* 输入:2012-04-04 00:00:00,2012.2.2,2012/4/7
                 * 输出:2012-04-04
                 * */
                function flitDate(dStr){
                    if(dStr){
                        var dreg = /(d{4})([-/.])(d{1,2})2(d{1,2})/;
                        var sval = dStr.match(dreg)[0].replace(dreg,"$1-$3-$4");
                        return sval;
                    }else{
                        return dStr;
                    }
                }
    
                function fill1Simple(dom,data1){
                    if(dom == undefined){ return;}
    
                    if(dom.className.match(/combo-value/i)){
                        fill1EasyUI(dom,data1); //按照easyUI的法则填充数据
                    }else{
                        var $dom = $(dom);
                        if($dom.is("span.om-combo>input")){
                            $dom.omCombo('value',data1)
                        }else{
                            dom.value = data1; //普通的html元素赋值
                        }
                    }
                }
    
                //把网页上需要额外对照的数据也加到填充数据中
                $.each(rt,function(key,value){
                    if(jsonData[key]){
                        jsonData[value.replace(/\*/g,'')]=jsonData[key];
                    }
                });
    
                /* 填充数据的主函数
                 *
                 * 是用表单为主循环还是数据为主循环快???要做测试。
                 * 测试结果:以表单为主循环,必需将EasyUI和一般表单项分开处理
                 *
                 * 必须要把radio,checkbox放在同一起处理,因为你也不清楚对照表里面的项目是text还是radio
                 * */
                var nameflag="";//name标记  如果找到有name相同的 data,那就设置标记,以便循环只运行一次
                $("input[name],textArea[name],select[name]",formObj).each(function(){
                    //在实际项目中,有这样的需要:JSON数据key总是大写,也要填充到页面;按表单中属性为fillBack的去填充,故在此进行扩充
                    var filldata1 = jsonData[this.name] || jsonData[this.name.toUpperCase()] || jsonData[this.getAttribute("fillBack")];
                    if(jsonData[this.name] === 0 || jsonData[this.name.toUpperCase()] === 0 || jsonData[this.getAttribute("fillBack")] === 0){
                        filldata1 = 0;
                    }
                    if(filldata1 === undefined || filldata1 === "" || filldata1 === null|| filldata1 === "null"){
                        return;
                    }else{
                        if(/radio/i.test(this.getAttribute("type"))){
                            if(this.name==nameflag){ return; }
                            nameflag = this.name;
                            $("input[name='"+ nameflag +"'][value=" + $.trim(filldata1) + "]").prop("checked",true);
                        }else if(/checkbox/i.test(this.getAttribute("type"))){
                            if(this.name==nameflag){ return; }
                            nameflag = this.name;
    
                            $("input[name='"+ nameflag +"']").prop("checked",false)//首先要清空原有数据
                            $.each(filldata1.split(','),function(k,v){
                                $("input[name='"+ nameflag +"'][value='" + $.trim(v) + "']").prop("checked",true);
                            })
                        }else{
                            this.value = "";//首先要清空原有数据
                            fill1Simple(this,filldata1);
                        }
                    }
                });
    
                if(typeof conf.callBack == "function"){
                    conf.callBack(jsonData);
                }
            }
        });
    }(jQuery);
    ```
    
  • 相关阅读:
    XV6文件系统
    XV6锁
    PC硬件以及引导加载器
    XV6第一个进程
    XV6操作系统接口
    XV6环境搭建及注意事项
    XV6文件系统
    XV6上下文切换
    少走弯路的十条忠告
    LIBCMTD.lib与libcpmtd冲突的解决方法。
  • 原文地址:https://www.cnblogs.com/p2227/p/3537708.html
Copyright © 2020-2023  润新知