`
ham
  • 浏览: 79967 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于如何编写灵活定制列样式的Grid控件

阅读更多
Grid控件,相信很多人都已经写过,或者重构过了。
对于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)
分享到:
评论
8 楼 achun 2008-08-21  
<p>还有,你忘了ajax了.可以把大模板分成小的子模板写,让后用ajax异步的方法去调用编译.<br/>就算模板很大,可是不会是所有的模板都一下子全都表现在页面上吧,<br/>就算要全都表现,ajax分步调用模板,分别编译然后表现出来也是没有问题的呀!</p>
<p>你用firefox+firebug监视一下</p>
<p>http://ne.16lo.com/</p>
<p>就会发现这个是如何运作的了.在这个 nicEdit 打包器里,nicEdit 的原文件,不是后台的php提供的,也不是预定义的变量,而是通过http服务器的目录列表用ajax的方法的到的,后台几乎就没有什么东西,全在前台.包括我写的那个flash,是用来把nicEdit里面模块的一个个gif图标文件合并成一个gif文件的,也抛弃了后台合并的方法,完全用flash在前台实现(当然上传后是要后台存储成文件的),我这样做的目的就是要充分发挥前台的威力,只要可以用前台的技术手段完成,我绝对不在后台做.</p>
<p>如果照这样的思路做程序,后台将空前简单.那后台早晚会被我用c/c++,D之类的语言改写的.</p>
<p>什么php,asp,jsp,java都下岗吧.本地机器码才是王道.配合高性能的linux,节省了多少资源呀!</p>
<p>服务器,内存,硬盘,还有电费,这可不是一笔小开支.</p>
7 楼 achun 2008-08-21  
<div class='quote_title'>ham 写道</div>
<div class='quote_div'>昨天晚上专门看了一下jCT,真的很神奇啊。且不论它到底能够在哪些地方进行使用,只是它的这种思维就很难得了,利用js实现编译器的功能来解析文档并执行脚本,而且代码非常精练。感觉achun的思维很清晰,但我一句也看不懂。哈哈。<br/><br/>很好奇achun兄是利用怎么样的一种思路来编写jCT.js的,能不能简单介绍下。<br/><br/>另外,如果可以结合jCT来编写js控件,那么对于控件的可定制性将大大提高啊(控件写多了,难免会向这个方向去想。嘿嘿)。不过,对于js这种运行速度很慢的的语言来说,利用js来解析jCT脚本,如果页面大了一点,就算没有用到正则,那它的速度还是个问题啊。achun有这方面的考虑吗?</div>
<p> </p>
<p>jCT一路走到现在是分了3个阶段的,看看</p>
<p><a href='http://jsct.googlecode.com/svn/trunk/jCT/'>http://jsct.googlecode.com/svn/trunk/jCT/</a></p>
<p>源码里的</p>
<p>jct1.js 第一版,完全是没有经验的摸索<br/>jct2.js 第二版,代码上主要改进了速度,和结构的合理性,功能上存储模板是特色</p>
<p>jct.js   第三版,彻底觉悟了,前面已经叙述过了,可惜的是在写第三版的时候我并没有意识到,这种方法其实和php,asp,jsp如出一辙.完全是一路走下来的结果.如果早有这个觉悟,也不至于经历了半年呀!</p>
<p> </p>
<p>速度你绝对不要担心,我一个正则都没有用就是考虑到速度的问题.正则真的很慢.</p>
<p> </p>
<p>至于jCT使用的问题,有共性的问题大概有:</p>
<p><strong>模板写于何处</strong>:三种情况</p>
<p>T1:浏览器调入的第一页面上:</p>
<p>T2:ajax加载外部独立的 模板文件</p>
<p>T3:预先把编译好的jct对象存储为js文件,直接加载</p>
<p><strong>模板如何调用</strong>:</p>
<p>首先:构建jCT前期对象.这个形式是肯定需要的</p>
<pre name='code' class='js'>var jctobj=new jCT(模板源代码,模板所在相对web根的绝对路径);</pre>
 
<p>模板源代码是必须的</p>
<p>绝对路径是我在使用中发现的一个很必要的参数,可以应用于ajax加载外部独立的 模板文件用,作用如何,用到了就明白了.</p>
<p>说是前期对象,原因是这个时候完整的jCT对象并没有生成.</p>
<pre name='code' class='js'>jctobj.Build();//这才是真正的构建jct对象,只所以要把这个独立出来是因为有ReBuild的方法,ReBuild是干什么用的,我还真是一句两句的说不清
jctobj.Exec(数据);//执行
</pre>
 
<p><strong>模板预览特色带来的问题</strong>:就是编译前后视觉一致性问题</p>
<p>写的模板一般都有样式的,由于jCT的文法特色,即便是直接在浏览器里调入模板,不进行编译运行,也可以看到设计的样子,这就是预览支持.</p>
<p>但是如果这样写模板了,那模板就会有一个完整的xhtml结构,包括 head 里的 meta,link,title,script等重要标记.</p>
<p>如果采用T1方式,这个基本上就没有问题.</p>
<p>如果采用T2方式,那就要对这些重要标签进行处理,最后应该传入jCT的模板源代码大多是body里的内容.</p>
<p>如果采用T3方式,很明显问题就更多,不过想想就知道T3是可以用做特殊情况的,比如控件.</p>
<p>而我现在都是在使用T2的方式,我解决的方法很简单:利用ajax可以直接生成xml对象的特点来加载模板.而对于xml对象来说分析处理xml树就方便多了.</p>
<p>可是实现的时候就出现了浏览器兼容性问题.具体就不说了.直接说我的结论:</p>
<p>模板的书写采用不完全的xhtml规范,也就是直接以html标记开头的xhtml模板.</p>
<p>然后ajax加载的时候挂上一个特殊的url参数,配置http服务器,遇到这个参数就输出</p>
<p>Content-Type: application/xml</p>
<p>以便让ajax生成正确的xml对象.</p>
<p>这样就可以实现预览和ajax的xml对象兼容的要求了.</p>
<p><strong>其他</strong>:由于jCT是模板编译器,是最大的支持了javascript,应该说是仅仅实现了无缝支持javascript.所以其他的问题应该都是javascript使用的问题,而不是jCT的问题.</p>
<p>看看jCT的源代码和实现方式就明白了,活脱脱的一个在前台完成的<strong>嵌入javascript模板编译器</strong>,完成编译就是他的最大作用,其他的靠自己了.</p>
6 楼 ham 2008-08-21  
昨天晚上专门看了一下jCT,真的很神奇啊。且不论它到底能够在哪些地方进行使用,只是它的这种思维就很难得了,利用js实现编译器的功能来解析文档并执行脚本,而且代码非常精练。感觉achun的思维很清晰,但我一句也看不懂。哈哈。

很好奇achun兄是利用怎么样的一种思路来编写jCT.js的,能不能简单介绍下。

另外,如果可以结合jCT来编写js控件,那么对于控件的可定制性将大大提高啊(控件写多了,难免会向这个方向去想。嘿嘿)。不过,对于js这种运行速度很慢的的语言来说,利用js来解析jCT脚本,如果页面大了一点,就算没有用到正则,那它的速度还是个问题啊。achun有这方面的考虑吗?
5 楼 achun 2008-08-20  
<div class='quote_title'>ham 写道</div>
<div class='quote_div'>我这个帖子只是说明了一种思路,至于这种思路是好是坏,只有让大家鉴定了。<br/><br/>模板我没有接触过。<br/>只是突然想到了这种方法,然后就开始用了。<br/><br/>直接写一套模板当然很好,但要看公司及你个人有没有这个这个能力去做。<br/>我们公司由于开发平台是自主的,比较特殊。用外面的框架没办法很好的和公司平台进行兼容。所以那些控件都是自己重新开发的。<br/>就算是搞个模板,也需要能够很好的和公司平台进行兼容。本来外面的模板技术就少,再加上这个条件,那几乎就是没有了。所以只能够结合自己的平台,再开发一套。<br/><br/>另外,能不能帮忙讲解一下模板是什么……<img src='../../../../../../images/smiles/icon_biggrin.gif' alt=''/><br/>我去看了一下你经常说的jCT,但还没搞清它具体是用来干什么的。<br/><br/>----------------------------------------------------------<br/>Ps:由于发帖时只是按照自己的思路直接写的代码,没有经过测试。等到发完帖子之后,才发现功能有很大问题,但已经帖发出来这么久了,就不想再修改了。以后有机再发一篇详细点的吧。</div>
<p><br/>很荣幸能向你介绍jCT,jCT是 MIT License,可以放心用于商业使用。</p>
<p>首先,jCT 经过了3个版本后,已经发生了本质的变化。我直接说目前 jCT 3 的设计吧。</p>
<p> </p>
<p>1.对于 jCT 3 来说模板这个说法其实不能诠释她的方法,用 嵌入javascript 编译器描述也许更合适(其实是我找不到其他的词).</p>
<p>首先我反问一下,php,asp,jsp文件的文法(可以嵌入html代码)是什么?可以称作模板么?</p>
<p>如果说是模板,那jCT 3也是模板。因为 jCT 3的文件在文法结构上几乎和上述3种语言具有一样的嵌入html代码的特性(到底是谁被嵌入?是html?还是php,asp,jsp?庄周梦蝶呀)。</p>
<p>如果不是,那jCT 3也不是模板,道理同上。</p>
<p>2.认识到上面的说法,也就明白了 jCT3是把 jCT3 源文件编译成javascript对象的一个编译器(其实javascript模板都是干这个的)。</p>
<p>就像 php 把php文件编译成内部的我们看不见的可解释执行结构一样。</p>
<p>3.php,asp,jsp能做什么?当然是他们能做的事情,同理jCT3最终生成的是javascript对象,那javascript有的能做的她都支持。</p>
<p>4.具体点就是如果你把一个php,asp或jsp文件输出html文件的例子,拿过来看,在把jCT3做同样事情的文件来比较,你发现本质上他们的文法结构是一样的。</p>
<p>当然这里面有一个数据来源问题,其实这不是jCT3应该负责的事情,因为jCT3支持所有的javascript语法,所以要数据的话应该自己写javascript代码去取得数据</p>
<p>简单的例子:用&lt;!--- --&gt;做jCT3的文法符号,jCT3支持自定义的,且内置了3种不同的文法符号,而且是自动识别</p>
<pre name='code' class='html'>&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;!---
/*+Exec*/
var D=['aaa','bbb','cccc'];
/*...*/
$(‘body').html(this.GetView());
--&gt;
&lt;ul&gt;
&lt;!---for(var I=0;I&lt;D.length;I++){--&gt;
&lt;li&gt;+-D[I]-+&lt;/li&gt;
&lt;!---}--&gt;
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>经过jCT3运行后结果就是3个 li 了,这个文法看上去是不是和php,asp,jsp极其相像!</p>
<p>当然要在这里说全面解释清楚的话真的不容易,感兴趣的话就细看看我blog上的专题吧。</p>
<p>有具体问题我们继续讨论。</p>
4 楼 ham 2008-08-20  
我这个帖子只是说明了一种思路,至于这种思路是好是坏,只有让大家鉴定了。

模板我没有接触过。
只是突然想到了这种方法,然后就开始用了。

直接写一套模板当然很好,但要看公司及你个人有没有这个这个能力去做。
我们公司由于开发平台是自主的,比较特殊。用外面的框架没办法很好的和公司平台进行兼容。所以那些控件都是自己重新开发的。
就算是搞个模板,也需要能够很好的和公司平台进行兼容。本来外面的模板技术就少,再加上这个条件,那几乎就是没有了。所以只能够结合自己的平台,再开发一套。

另外,能不能帮忙讲解一下模板是什么……
我去看了一下你经常说的jCT,但还没搞清它具体是用来干什么的。

----------------------------------------------------------
Ps:由于发帖时只是按照自己的思路直接写的代码,没有经过测试。等到发完帖子之后,才发现功能有很大问题,但已经帖发出来这么久了,就不想再修改了。以后有机再发一篇详细点的吧。
3 楼 achun 2008-08-20  
ham 这种方法很明显是借鉴了 模板的思路.
可是既然 你发现了模板的思路是一种通用的思路,
为什么不直接基于模板的思路去做这个呢?
目前这种修修补补的方法,我觉得真的不可取.
把 grid 这种需求作成一个整体的控件,不如把里面的各种子控件拆分出来.
grid从某种角度看,就是具有
1.grid的样式
2.获取/修改数据的支持
3.数据相关性操作的支持
4.灵活性

与其费劲写个超强的控件,不然用 模板技术进行 组装

有点 给模板做宣传的意味.可事实就是这样,WEB开发模板真的是不二法宝.
看看 php,asp,jsp吧,他们的实现本身就是一个后台的模板
2 楼 ham 2008-08-20  
kimmking 写道
很小白的问问:
Grid控件是啥?

表格控件..............
1 楼 kimmking 2008-08-20  
很小白的问问:
Grid控件是啥?

相关推荐

Global site tag (gtag.js) - Google Analytics