锁定老帖子 主题:关于如何编写灵活定制列样式的Grid控件
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-20
对于Grid中的某些功能,实现起来会比较头疼。其中很重要的一个就是定制列样式的实现,如将列设为单选框,下拉框…等等。网上的Grid控件的做法,几乎都是使用的内部定义好的一些样式,使用时进行指定,虽说实现了大部分的需求功能,但对于某些特殊的自定义功能,想实现起来就很没什么办法了,只有扩展源代码。 做Grid控件有一段时间了,被这个问题烦了有一段时间。开始的时候也是模拟网上部分Grid的实现方式,自定义了部分列样式,封装在Grid中,但面对着各种需求的自定义样式,感觉越来越力不从心。 经过一段时间的摸索之后,终找到了一种个人最好的实现方式,对于实现某些自定义样式很方便,也很灵活。可以有效的将列的样式和Grid控件分离开来。实现了高定制化的Grid。 还是用代码来说明吧: Grid控件中用实现自定义表格的伪代码: function myGridConfig(id){ this.__id=id; var _self=this; ... _self.createHead=function(titles){ this.titles=titles;//设列标题以数组形式存储 ... } _self.getdata=function(){ //从数据库读取数据,并以二维数组的方式返回。 } _self.createBody=function(){ ... var grid=...//表格对象。 var data=getdata(); for(var i=0;i<data.length;i++){ var cells=data[i]; var tr = grid.insertRow();//添加一行。 for(var j=0;j<this.titles.length;j++){ var td=document.createElement("td"); if(document.all[this.__id+"_col_"+j]){//查找页面中有没有id为 id_col_index 形式的元素.这里使用了IE特有的document.all语法。 var customHtml = document.all[this.__id+"_col_"+j].innerHTML; /**替换掉指定部分(即"_id_","_value_")的值。 通常的数据中,第一行都是从数据库中读取出来的id,所以此处将_id_替换为cells[0].**/ customHtml = customHtml.replace(/_id_/g,cells[0]).replace(/_value_/g,cells[j]); td.innerHTML=customHtml; }else{ td.innerHTML=cells[j]?cells[j]:""; } tr.appendChild(td);//将单元格TD加入TR。 } grid.appendChild(tr);//将TR加入表格。 } ... } ... } 有了以上的代码,那么在调用Grid的页面,就可以很方便的实现自定义列样式了。假设从数据库中通过getdata()方法得到的数据为以下形式: [ ["001","张三","男"], ["002","李四","男"], ["003","王五","男"] ] 如想在最后一列加上一个“操作”列。则可以写一个div,将所要实现的功能放在div之中: //这里是myGrid_col_3..如果Grid控件的__id为"myGrid",它的第四列就会被替换成为其内部的内容。 <div id="myGrid_col_3" style="display:none;"> <a onclick="edit('_id_');">编辑</a> <a onclick="del('_id_');">删除</a> //由于在上面的代码中,_id_会被替换为data中的第一列的值,并赋到相应的单元格内。 //所以每点击编辑,就会调用edit方法。并将当前行的第一列值传进去。就可以对专门的某一条数据进行操作。 </div> <script> function.onload=function(){ var gridConfig=new myGridConfig("myGrid"); var titles=["编号","姓名","性别","操作"]//存储Grid标题的数组 gridConfig.createHead(titles); gridConfig.createBody(); } </script> 是不是很方便呢? 这样这种方式的好处就是,样式代码和Grid控件分离开了,两者不再耦合在一起,当想要修改某一列的样式时,只要修改那一列的样式所在的div的内容即可。你想到什么样的样式,就可以写什么样的样式,只要你想得到,几乎都可以通过相应的方式实现。 当然,一般当前行数据的id是不会显示在代码中,而是是被隐藏起来的。隐藏的功能只要在myGridConfig中编写相应的代码进行实现就可以了,这里只是讨论自定义列样式的功能,所以就不涉及那方面了。 如果各位对我这个实现有什么看法和建议或者不清楚的地方,欢迎交流和讨论。 另外如果各位有各好的定制列样式的方法,各位是怎么做的呢? ------------------------------------------------------------------------------------------------ 本来想把Grid的代码也共享过来,但由公司是使用的平台的特殊性,我写的那些控件都是以特定的格式编写和调用的,Grid控件离开平台就无法运行,要修改很大一部分代码,所以就没做这方面的工作。 (08-20 1:08 by ham) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-08-20
很小白的问问:
Grid控件是啥? |
|
返回顶楼 | |
发表时间:2008-08-20
kimmking 写道 很小白的问问:
Grid控件是啥? 表格控件.............. |
|
返回顶楼 | |
发表时间:2008-08-20
ham 这种方法很明显是借鉴了 模板的思路.
可是既然 你发现了模板的思路是一种通用的思路, 为什么不直接基于模板的思路去做这个呢? 目前这种修修补补的方法,我觉得真的不可取. 把 grid 这种需求作成一个整体的控件,不如把里面的各种子控件拆分出来. grid从某种角度看,就是具有 1.grid的样式 2.获取/修改数据的支持 3.数据相关性操作的支持 4.灵活性 与其费劲写个超强的控件,不然用 模板技术进行 组装 有点 给模板做宣传的意味.可事实就是这样,WEB开发模板真的是不二法宝. 看看 php,asp,jsp吧,他们的实现本身就是一个后台的模板 |
|
返回顶楼 | |
发表时间:2008-08-20
我这个帖子只是说明了一种思路,至于这种思路是好是坏,只有让大家鉴定了。
模板我没有接触过。 只是突然想到了这种方法,然后就开始用了。 直接写一套模板当然很好,但要看公司及你个人有没有这个这个能力去做。 我们公司由于开发平台是自主的,比较特殊。用外面的框架没办法很好的和公司平台进行兼容。所以那些控件都是自己重新开发的。 就算是搞个模板,也需要能够很好的和公司平台进行兼容。本来外面的模板技术就少,再加上这个条件,那几乎就是没有了。所以只能够结合自己的平台,再开发一套。 另外,能不能帮忙讲解一下模板是什么…… ![]() 我去看了一下你经常说的jCT,但还没搞清它具体是用来干什么的。 ---------------------------------------------------------- Ps:由于发帖时只是按照自己的思路直接写的代码,没有经过测试。等到发完帖子之后,才发现功能有很大问题,但已经帖发出来这么久了,就不想再修改了。以后有机再发一篇详细点的吧。 |
|
返回顶楼 | |
发表时间:2008-08-20
ham 写道
我这个帖子只是说明了一种思路,至于这种思路是好是坏,只有让大家鉴定了。
模板我没有接触过。 只是突然想到了这种方法,然后就开始用了。 直接写一套模板当然很好,但要看公司及你个人有没有这个这个能力去做。 我们公司由于开发平台是自主的,比较特殊。用外面的框架没办法很好的和公司平台进行兼容。所以那些控件都是自己重新开发的。 就算是搞个模板,也需要能够很好的和公司平台进行兼容。本来外面的模板技术就少,再加上这个条件,那几乎就是没有了。所以只能够结合自己的平台,再开发一套。 另外,能不能帮忙讲解一下模板是什么…… ![]() 我去看了一下你经常说的jCT,但还没搞清它具体是用来干什么的。 ---------------------------------------------------------- Ps:由于发帖时只是按照自己的思路直接写的代码,没有经过测试。等到发完帖子之后,才发现功能有很大问题,但已经帖发出来这么久了,就不想再修改了。以后有机再发一篇详细点的吧。
首先,jCT 经过了3个版本后,已经发生了本质的变化。我直接说目前 jCT 3 的设计吧。
1.对于 jCT 3 来说模板这个说法其实不能诠释她的方法,用 嵌入javascript 编译器描述也许更合适(其实是我找不到其他的词). 首先我反问一下,php,asp,jsp文件的文法(可以嵌入html代码)是什么?可以称作模板么? 如果说是模板,那jCT 3也是模板。因为 jCT 3的文件在文法结构上几乎和上述3种语言具有一样的嵌入html代码的特性(到底是谁被嵌入?是html?还是php,asp,jsp?庄周梦蝶呀)。 如果不是,那jCT 3也不是模板,道理同上。 2.认识到上面的说法,也就明白了 jCT3是把 jCT3 源文件编译成javascript对象的一个编译器(其实javascript模板都是干这个的)。 就像 php 把php文件编译成内部的我们看不见的可解释执行结构一样。 3.php,asp,jsp能做什么?当然是他们能做的事情,同理jCT3最终生成的是javascript对象,那javascript有的能做的她都支持。 4.具体点就是如果你把一个php,asp或jsp文件输出html文件的例子,拿过来看,在把jCT3做同样事情的文件来比较,你发现本质上他们的文法结构是一样的。 当然这里面有一个数据来源问题,其实这不是jCT3应该负责的事情,因为jCT3支持所有的javascript语法,所以要数据的话应该自己写javascript代码去取得数据 简单的例子:用<!--- -->做jCT3的文法符号,jCT3支持自定义的,且内置了3种不同的文法符号,而且是自动识别 <html> <head> </head> <body> <!--- /*+Exec*/ var D=['aaa','bbb','cccc']; /*...*/ $(‘body').html(this.GetView()); --> <ul> <!---for(var I=0;I<D.length;I++){--> <li>+-D[I]-+</li> <!---}--> </ul> </body> </html> 经过jCT3运行后结果就是3个 li 了,这个文法看上去是不是和php,asp,jsp极其相像! 当然要在这里说全面解释清楚的话真的不容易,感兴趣的话就细看看我blog上的专题吧。 有具体问题我们继续讨论。 |
|
返回顶楼 | |
发表时间:2008-08-21
昨天晚上专门看了一下jCT,真的很神奇啊。且不论它到底能够在哪些地方进行使用,只是它的这种思维就很难得了,利用js实现编译器的功能来解析文档并执行脚本,而且代码非常精练。感觉achun的思维很清晰,但我一句也看不懂。哈哈。
很好奇achun兄是利用怎么样的一种思路来编写jCT.js的,能不能简单介绍下。 另外,如果可以结合jCT来编写js控件,那么对于控件的可定制性将大大提高啊(控件写多了,难免会向这个方向去想。嘿嘿)。不过,对于js这种运行速度很慢的的语言来说,利用js来解析jCT脚本,如果页面大了一点,就算没有用到正则,那它的速度还是个问题啊。achun有这方面的考虑吗? |
|
返回顶楼 | |
发表时间:2008-08-21
ham 写道
昨天晚上专门看了一下jCT,真的很神奇啊。且不论它到底能够在哪些地方进行使用,只是它的这种思维就很难得了,利用js实现编译器的功能来解析文档并执行脚本,而且代码非常精练。感觉achun的思维很清晰,但我一句也看不懂。哈哈。
很好奇achun兄是利用怎么样的一种思路来编写jCT.js的,能不能简单介绍下。 另外,如果可以结合jCT来编写js控件,那么对于控件的可定制性将大大提高啊(控件写多了,难免会向这个方向去想。嘿嘿)。不过,对于js这种运行速度很慢的的语言来说,利用js来解析jCT脚本,如果页面大了一点,就算没有用到正则,那它的速度还是个问题啊。achun有这方面的考虑吗?
jCT一路走到现在是分了3个阶段的,看看 http://jsct.googlecode.com/svn/trunk/jCT/ 源码里的 jct1.js 第一版,完全是没有经验的摸索 jct.js 第三版,彻底觉悟了,前面已经叙述过了,可惜的是在写第三版的时候我并没有意识到,这种方法其实和php,asp,jsp如出一辙.完全是一路走下来的结果.如果早有这个觉悟,也不至于经历了半年呀!
速度你绝对不要担心,我一个正则都没有用就是考虑到速度的问题.正则真的很慢.
至于jCT使用的问题,有共性的问题大概有: 模板写于何处:三种情况 T1:浏览器调入的第一页面上: T2:ajax加载外部独立的 模板文件 T3:预先把编译好的jct对象存储为js文件,直接加载 模板如何调用: 首先:构建jCT前期对象.这个形式是肯定需要的 var jctobj=new jCT(模板源代码,模板所在相对web根的绝对路径); 模板源代码是必须的 绝对路径是我在使用中发现的一个很必要的参数,可以应用于ajax加载外部独立的 模板文件用,作用如何,用到了就明白了. 说是前期对象,原因是这个时候完整的jCT对象并没有生成. jctobj.Build();//这才是真正的构建jct对象,只所以要把这个独立出来是因为有ReBuild的方法,ReBuild是干什么用的,我还真是一句两句的说不清 jctobj.Exec(数据);//执行 模板预览特色带来的问题:就是编译前后视觉一致性问题 写的模板一般都有样式的,由于jCT的文法特色,即便是直接在浏览器里调入模板,不进行编译运行,也可以看到设计的样子,这就是预览支持. 但是如果这样写模板了,那模板就会有一个完整的xhtml结构,包括 head 里的 meta,link,title,script等重要标记. 如果采用T1方式,这个基本上就没有问题. 如果采用T2方式,那就要对这些重要标签进行处理,最后应该传入jCT的模板源代码大多是body里的内容. 如果采用T3方式,很明显问题就更多,不过想想就知道T3是可以用做特殊情况的,比如控件. 而我现在都是在使用T2的方式,我解决的方法很简单:利用ajax可以直接生成xml对象的特点来加载模板.而对于xml对象来说分析处理xml树就方便多了. 可是实现的时候就出现了浏览器兼容性问题.具体就不说了.直接说我的结论: 模板的书写采用不完全的xhtml规范,也就是直接以html标记开头的xhtml模板. 然后ajax加载的时候挂上一个特殊的url参数,配置http服务器,遇到这个参数就输出 Content-Type: application/xml 以便让ajax生成正确的xml对象. 这样就可以实现预览和ajax的xml对象兼容的要求了. 其他:由于jCT是模板编译器,是最大的支持了javascript,应该说是仅仅实现了无缝支持javascript.所以其他的问题应该都是javascript使用的问题,而不是jCT的问题. 看看jCT的源代码和实现方式就明白了,活脱脱的一个在前台完成的嵌入javascript模板编译器,完成编译就是他的最大作用,其他的靠自己了. |
|
返回顶楼 | |
发表时间:2008-08-21
还有,你忘了ajax了.可以把大模板分成小的子模板写,让后用ajax异步的方法去调用编译. 你用firefox+firebug监视一下 http://ne.16lo.com/ 就会发现这个是如何运作的了.在这个 nicEdit 打包器里,nicEdit 的原文件,不是后台的php提供的,也不是预定义的变量,而是通过http服务器的目录列表用ajax的方法的到的,后台几乎就没有什么东西,全在前台.包括我写的那个flash,是用来把nicEdit里面模块的一个个gif图标文件合并成一个gif文件的,也抛弃了后台合并的方法,完全用flash在前台实现(当然上传后是要后台存储成文件的),我这样做的目的就是要充分发挥前台的威力,只要可以用前台的技术手段完成,我绝对不在后台做. 如果照这样的思路做程序,后台将空前简单.那后台早晚会被我用c/c++,D之类的语言改写的. 什么php,asp,jsp,java都下岗吧.本地机器码才是王道.配合高性能的linux,节省了多少资源呀! 服务器,内存,硬盘,还有电费,这可不是一笔小开支. |
|
返回顶楼 | |
浏览 4953 次