标签:
这周接到的任务是动态生成某datagrid的标题,并且要能够根据动态生成的标题来再去数据库中找到相应的值并拼接赋值上去。
项目经理给我的静态页面如下:
左边一列为车型,右边的上面是零件号,下面是固定的,直接循环生成就行,但是数量不一定,需要动态生成。里面的数据是自动加载的。
后台数据库中能够得到的数据大概是这个形式:
这个问题的难点如下:
1.动态生成datagrid的column。
2.将SQL拿出来的数据拼接成前台需要的横行形式,也就是列转行。
先说下解决的思路和方法。
首先是datagrid。
一般datagrid在使用中都是预先定义好column,这个在官方模板里面是有的,在此不赘述。
但是在这里是不可以的。因为零件号并不固定,所以前台无法写死。在此感谢http://blog.csdn.net/yanjunlu/article/details/8017167博主,提供了很好的解决方法。不过他的方法仍然在静态的基础上,所以需要做一点扩展。
1 function fetchData(msgId) { 2 //var msgId = GetQueryString("avonMsgId"); 3 4 //var msgId = 1; 5 var s = ""; 6 s = "[["; //用来拼接需要的标题字段 7 s = s + "{ field:‘ACC_NO‘, title:‘Accessories‘, width:100, rowspan:2, sortable:true, align:‘left‘ },"; 8 $.ajax({ 9 type : ‘POST‘, 10 url : ‘/TCM/aekoDistribute/getDistribute‘, /*远程获取数据地址*/ 11 data : { 12 msgId : msgId, 13 }, 14 success : function(response) { 15 s = s + distributeOne(response); //得到所有需要的标题字段 16 options = {}; 17 options.queryParams = { 18 msgId: msgId 19 }; 20 options.columns = eval(s); 21 $("#dispatch_accessories_datagrid").datagrid(options); 22 $("#dispatch_accessories_datagrid").datagrid(‘reload‘); 23 }, 24 error : function(response) { 25 alert("read item error!"); 26 } 27 }); 28 } 29 30 function distributeOne(response) { 31 var a = ""; 32 a = a + "{title : ‘" + response[0] + "‘, colspan: 2}"; 33 for (var i =1;i< response.length; i++) { 34 a = a + ",{title: ‘" + response[i] + "‘, colspan: 2 }"; 35 } 36 a = a + "],["; 37 a = a + "{field : ‘" + response[0] + "_dept‘, title: ‘person‘, width : 120, sortable : true, align : ‘left‘},{field : ‘" + response[0] + "_num‘, title: ‘number‘, width : 100, sortable : true, align:‘left‘}"; 38 for (var i =1; i<response.length; i++) { 39 a = a + ",{field : ‘" + response[i] + "_dept‘, title: ‘person‘, width : 120, sortable : true, align : ‘left‘},{field : ‘" + response[i] + "_num‘, title: ‘number‘, width : 100, sortable : true, align:‘left‘}"; 40 } 41 a = a + "]]"; 42 return a ; 43 }
其实基本原理就是分两步,首先是拼接出字符串形式的column格式,然后在option中赋值给其column属性,再去执行。
这里面的重点是我返回前台的值是
[390, 4J0, 4W0, 420, 7P0, 8F0, 8K0, 8RD, 8R0, 8T0, 9I0, 95B, 2KC, 3ED, 3Y0, 4GD, 4G0, 4G8, 4H0]
这样的list,所以取出来之后拼接就直接按顺序拿就好。而且上面的title生成的时候不要加field,否则会把下面两列的column给挤走,最后整个顺序就乱了。
真正的难点在第二步,也是耗费了我将近一天时间的难点。
第一个挑战在于行转列。你可以选择SQL直接去转,但是我懒得建立临时表,而且觉得麻烦,返回到前台也不知道什么格式。还想过在事务层重新拼接,但是因为返回格式抓不准的原因也放弃了。最终决定就直接把数据库的数据一个接一个在controll拼成list,大不了三个为一组去取就好。
最后返回的格式是这样:
[8K0907503, 390, 1, 4H0907503, 390, 1, 8K0907503, 4J0, 1, 4H0907503, 4J0, 1, 8K0907503, 4W0, 1, 4H0907503, 4W0, 1, 8K0907503, 420, 1, 4H0907503, 420, 1, 8K0907503, 7P0, 1, 4H0907503, 7P0, 1, 8K0907503, 8F0, 1, 4H0907503, 8F0, 1, 8K0907503, 8K0, 1, 4H0907503, 8K0, 1, 8K0907503, 8RD, 1, 4H0907503, 8RD, 1, 8K0907503, 8R0, 1, 4H0907503, 8R0, 1, 8K0907503, 8T0, 1, 4H0907503, 8T0, 1, 8K0907503, 9I0, 1, 4H0907503, 9I0, 1, 8K0907503, 95B, 1, 4H0907503, 95B, 1, 8K0907503, 2KC, 1, 4H0907503, 2KC, 1, 8K0907503, 3ED, 1, 4H0907503, 3ED, 1, 8K0907503, 3Y0, 2, 4H0907503, 3Y0, 2, 8K0907503, 4GD, 1, 4H0907503, 4GD, 1, 8K0907503, 4G0, 1, 4H0907503, 4G0, 1, 8K0907503, 4G8, 1, 4H0907503, 4G8, 1, 8K0907503, 4H0, 1, 4H0907503, 4H0, 1]
可以看出来三个为一组,很平衡。= =||
但是下面我再次尝试去拼接成字符串,就遇到了很多问题。包括逗号啊,转义啊,括号啊,一个不注意都不行。(顺便说一下项目要求的是IE8,所以完全不具备FF强大的自纠错能力,必须严格写对)
还有就是插入问题,当形成诸如
{‘ACC_NO‘ : ‘8K0907503‘,‘390_num‘:‘1‘,},{‘ACC_NO‘ : ‘4H0907503‘,‘390_num‘:‘1‘,}
的代码后,要插入
8K0907503, 4J0, 1,
然后形成
{‘ACC_NO‘ : ‘8K0907503‘,‘390_num‘:‘1‘,‘4J0_num‘:‘1‘,},{‘ACC_NO‘ : ‘4H0907503‘,‘390_num‘:‘1‘,}
这样的形式。看似简单,其实还是需要考虑一段时间。虽然据说js的replace能够用正则,但是我第一不熟正则,第二总是觉得正则容易错,所以最终采用了截取再拼接的方法:
1 var location = a.indexOf(response[b]); 2 var fore = a.substring(0,location); 3 var param = a.substring(location); 4 var c = ""; 5 c = c + "\"" + response[b+1] + "_num\":\"" + response[b+2] + "\",}"; 6 param = param.replace(/}/, c); 7 a = fore + param;
当一切都拼好后,我自以为是的写下了这一句:
1 $("#dispatch_accessories_datagrid").datagrid(‘loadData‘,data);
然后,一片寂静。。。
最后才想起来,这是赋值,不是静态标题,还要转成json data格式。少不了要按照data格式来重新拼接一番,最后的代码如下:
1 function fillData(msgId) { 2 var s = ""; 3 $.ajax({ 4 type: ‘POST‘, 5 url : ‘/TCM/aekoDistribute/haveAccNo‘, 6 data : { 7 msgId:msgId, 8 }, 9 success : function(response) { 10 s = s + haveAccNo(response); 11 data = $.parseJSON(s); 12 13 $("#dispatch_accessories_datagrid").datagrid(‘loadData‘,data); 14 $("#dispatch_accessories_datagrid").datagrid(‘reload‘); 15 } 16 }) 17 } 18 19 String.prototype.replaceAll = function(s1,s2){ 20 return this.replace(new RegExp(s1,"gm"),s2); 21 } 22 23 function haveAccNo(response) { 24 var a = ""; 25 a = a + "{\"total\":" + 1 + ", \"rows\":["; 26 27 /* a = a + "{‘ACC_NO‘ : ‘" + response[0] + "‘, ‘" + response[1] + "_num‘ : ‘" + response[2] + "‘," 28 for (var i = 3; i < response.length; i+3) { 29 for 30 a = a + ",{‘ACC_NO‘ : ‘" + response[i] + "‘, ‘" + response[i+1] + "_num‘ : ‘" + response[i+2] + "‘,}"; 31 } */ 32 //先把response%3余0的存入一个数组,然后检查是否存在 33 var arr = new Array(); 34 arr.push(response[0]); 35 a = a + "{\"ACC_NO\" : \""+ response[0] + "\",\"" + response[1] + "_num\":\"" + response[2] + "\",}"; 36 var b = 3; 37 for (;b < response.length; b = b+3) { 38 if ($.inArray(response[b], arr) == -1){ //数组中不存在 39 arr.push(response[b]); 40 a = a + ",{\"ACC_NO\" : \""+ response[b] + "\",\"" + response[b+1] + "_num\":\"" + response[b+2] + "\",}"; 41 } else { //数组中存在 42 var location = a.indexOf(response[b]); 43 var fore = a.substring(0,location); 44 var param = a.substring(location); 45 var c = ""; 46 c = c + "\"" + response[b+1] + "_num\":\"" + response[b+2] + "\",}"; 47 param = param.replace(/}/, c); 48 a = fore + param; 49 } 50 } 51 a = a.replaceAll(",}", "}"); 52 a = a + "]}"; 53 return a ; 54 }
至此全部完成,最终结果如下:
至于person,那是数据问题,不是我的问题:)
现在的方法以后稍微扩展就能够适用于datagrid几乎所有动态生成的方面。
标签:
原文地址:http://www.cnblogs.com/garygeng/p/5040088.html