#把JSON數據載入到頁面表單的兩種思路(對easyui自帶方法進行改進) ##背景 項目中常常須要把JSON數據填充到頁面表單,一開始我使用easyui自帶的form load方法,以爲效率很低,常常在載入數據的時候有假死現象(實際項目中的表單通常都100-200個字段以上),並且不能處理radio/checkbox的狀況。(easyui的思路是把它們都用combo去處理) ##思路 問題能夠轉化爲,如今有一堆JSON數據,有一個表單,多是一一對應的,要把這個數據填寫到表單上,通常說來有兩種思路 1. `方案一`針對數據,一個個選擇元素進行填充 2. `方案二`先選擇全部的元素,再針對數據進行填充 到底哪一種比較優呢? ##測試驗證 可能也有人大概想到較優方案,可是對於實事求是的我,仍是要寫些代碼去測試驗證 [個人測試例子](http://p2227.github.io/demo/loadForm/) 效果截圖:  ##結果 `方案二`的思路明顯要比`方案一`的優,並且查看原代碼後發現,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); ```