一直以来都想用jCT写出个WEB可视组件,本来打算从Grid入手做的,可是实际我做的时候发现如此的纠结
jCT本来就是模板技术,而组件可以认为是一种特定的模板技术(只不过模板被写道javascript代码里面了)
有想做组件这样的想法也不奇怪,因为模板所呈现的html原代码形式,改造扩充,调整结构,增加属性相对常规组件来说都是无比的方便。
可正是这种灵活性把jCT这个方向给毁了,因为,通用组件的模板代码完全体现不出来灵活性,而且还容易把事情搞复杂,
本来直接写html模板就已经很简单了,给个判断,加个循环,弄个分页都是很简单的事情
代码说话:注释用<!--注释-->
table部分
<!---///grid recorders--> <!--grid 是子模板对象名,recorders是要传入的记录对象--> <table> <thead> <!--表头部分,于其通过配置给出这些表头名不比多写几个th方便多少,这样你还可以增加自己的class等属性--> <tr> <th>用户名</th> <th>实名</th> <th>职位</th> </tr> </thead> <tbody> <!---this.Fn.V.push(this.rows.GetView(recorders));--> <!--这个语句以前没有出现过,其实这就是jCT内部实现视图时push进输出数组的语句, 这里通过建立一个grid下的rows子模板,把循环独立出来,然后调用this.rows.GetView(recorders)并push进输出数组 来完成tbody主体,这样做的理由后面会阐述,注意recorders参数被直接给传过去了 --> <!---///rows recorders--> <!---for(var i=0;i<recorders.length;i++){var l=recorders[i];--> <!--简单的循环输出了,这里面倒是可以写一段通用的代码,不过一样很大么?后面的阐述将否定他--> <tr name="/" value="user.get" class="submitdblc"> <td name="id" value="+-l.id-+"><span name="user">+-l.user-+</span></td> <!--注意id这个写的位置,这个是我应用里面的特殊需求,和上面的name="/"是配套的--> <td name="xingming">+-l.xingming-+</td> <td name="zhiwei">+-l.zhiwei-+</td> </tr> <!---}--> <!---///rows--> </tbody> </table> <div> <!---this.Fn.V.push(page.GetView(toPages(recorders)));--> <!--分页条控制输出,toPages是一个分页的函数,后面给出代码--> </div> <!---///grid--> <!--下面是分页条控制的模板,由于这个几乎是通用的结构所以独立出来--> <!---///page p--> <div class="page"> <fieldset> <!---for(var i=p.start;i<=p.end;i++){--> <button class="pageButton" value="+-i-+">+-i-+</button> <!---}--> <button class="pageButton" value="+-p.prev-+">上9页</button> <button class="pageButton" value="+-p.next-+">下9页</button> <button class="pageButton" value="+-p.count-+">共+-p.count-+页+-p.rows-+条</button> </fieldset> </div> <!---///page-->
分页的函数,在上面的代码里面要求后台返回的recorders对象里面直接含有相关参数,当然你可以把这些参数独立出来
/* *sets是分页所需要的信息,应该又后台输出的数据给出 * page_count总页数,这个后台没有给出的话也可以在js里计算,不过那就要提共每页有多少条记录了, * 我没有这样做,我习惯直接从后台计算出来,改造他当然不是什么大问题 * page_no当前显示的页 * rows_count记录总数 *range表示每次显示多少页的可选范围,我的习惯是9,因为个人喜好当前页优先处在中心位置这种形式 *当然这个函数也是这么写的,改造这个函数为常见的非中心分页的形式也很容易 *page返回值,有了这些值足以满足分页条的显示 * start:显示的开始页码 * end:显示的结束页码 * prev:前翻range页 * next:后翻range页 * no:当前页码 * rows:rows_count记录总数 */ function toPages (sets,range){ range=range||9; var rng=Math.floor(range/2); var page={start:0,end:0,prev:0,next:0}; page.count= sets.page_count|| 0; page.no = sets.page_no || 0; page.rows=sets.rows_count||0; if(!page.no) return page; page.start=page.no-rng; if(page.start<1) page.start=1; page.end=page.no+rng; if(page.end>page.count) page.end=page.count; page.prev=page.start-rng; if(page.prev<1) page.prev=1; page.next=page.end+rng; if(page.next>page.count) page.next=page.count; return page; }
那这里面有多少成分可以组件化!我想有这些方面吧,但问题和疑问同时存在
<td name="zhiwei" value="+-l.zhiwei-+">+-dict.zhiwei[l.zhiwei]-+</td>看上去td有value这样的属性很古怪,但是这确实让整个结构和取值便的简单了,
$('table.dbleditbox tr').live('dblclick',yourfunc);就OK了这样的话上面保留职位的原始int值就凸显出意义了,那有读者说这不是也可以组件化么!
<tr name="/" value="user.get" class="submitdblc">看到这种写法了吧,用一个特殊的name="/"而他的value就是提交给后台的请求方法,至于参数的变更可以用统一的开发模式来设计定义,一个方法就满足这类需求
到此问题终于找到关键,组件VS设计模式,我们已知的组件确实是绑定了自己的设计模式,对开发者确实有不少限制,前台模板确实给了开发者自由,但同时也需要开发者摸索出自己的一条路,才能通行无阻。
jCT的 纠结 :对于复杂应用,开发者要有自己的设计模式才能"得道飞升”,因为复杂应用用组件的需求更大,是仔细的研究组件,还是从设计模式入手,写自己的代码,是个艰难的选择
可以确定的是 前台 模板+设计模式的代码量,灵活性都要远胜于纯组件,前台模板下应该是根据应用需求分类设计模板,形成制定的“组件”,自己及时书写的组件,不要忘记了jCT是编译型模板,最后的执行代码是可以独立保存成独立的js的(看来应该写一个这样的导出方法了),貌似分页条就可以独立成组件,如此小的组件,我咋都觉得还不如直接复制粘贴模板的方便