在写这篇文章的时候我相信很多朋友都不明白我在说什么,会奇怪我这样的思路,问题就在这里,我的这种思路很难被认同.但是这种思路开发起来真的很快.请耐心看完所有的文章.
jCT发展到目前的第三版.除了jCT本身的变化外.我在使用的时候整个设计思路也都改变了.
对于模板技术来说,绝大多数是平面化,顺序化.也就是说
1.模板的结构和页面表现的结构一致--------------------平面化
2.模板成为视图的时候数据的装配是顺序进行的--------顺序化 (这个说法看了我下面的实现就会明白)
下面是我准备重新写的nicEditor打包工具模板部分.(注意<!---xxx-->是jCT的模板语法,<!--xx-->是我写的注释)
<!--1:下面一段用来确定页面的布局-->
<div id="" class=""><center class="fsh2 cwhite">选择 NicEdit 模块</center></div>
<div id="" class="">
<span>合并GIF图标文件:</span>
<input type='text' name="iconsfile" value="nicEditIcons.gif"/>
</div>
<div id="navmenu" class="" />
<div id="nelist" class="">nE List</div>
<!--这里用jCT重构语法,确定了执行的过程-->
<!---
/*+Main*/
function(D){
...//这一句将被jCT生成的实例主体过程替换
$('#mainbody').html(this.CTV.join(""));//把结果也就是上面的布局写入到#mainbody Element
$('#mainbody .abc').abc();//这是我写的一个jQuery插件 Action By Class name,可以忽视它
this.navmenu('#navmenu');//调用导航菜单
this.nelist();//调用从服务器取得的nicEditor的模块列表
}
-->
<!--1:布局结束-->
<!--jCT的Run语法,Run里的代码只运行一次.这里的例子相当于动态的定义了一个函数-->
<!---/*+Run*/
$.extend(App,{
test:function(){
alert($('img').attr('value'));
return false;
}
});
-->
<!--2:导航菜单部分, abc abc.lavaLamp(...) 是jQuery插件 Action By Class name 的执行方法-->
<!---/*+Child navmenu*/-->
<ul class="lavaLampBottomStyle bgc4 cwhite fwbold fsh4 abc abc.lavaLamp({fx:'easeOutBack',speed:700})">
<li class="inline"><a οnclick="return App.test();">测试</a></li>
<li class="inline"><a οnclick="return App.test();">下载</a></li>
</ul>
<!--道理同前面的重构-->
<!---/*+Main*/
function(){
...
var el=arguments[0];
if (!el) return this.CTV.join("");
$(el).html(this.CTV.join("")).find('.abc').abc();
}
-->
<!---/*-Child navmenu*/-->
<!--2:导航菜单部分结束-->
<!--3:nicEditor的模块列表-->
<!---/*+Child nelist*/-->
<table class="dlTable" cellpadding="0" cellspacing="0">
<tbody>
<!---for(var I=0;I<nelist.length;I++){-->
<tr class="core">
<td>
<img style="width:30px;height:30px;" class="checkbox" src="+-App.pixelGif-+" name="plugins[]" value="+-nelist[I]-+" />
<input name="plugins[]" value="+-nelist[I]-+" type='checkbox' class="none" />
</td>
<td class="pluginName">+-nelist[I]-+</td>
</tr>
<!---}-->
</tbody>
</table>
<!--道理同前面的重构,不过里面用到了一个thisCallback,后面叙述-->
<!---/*+Main*/
function(D){
if(arguments.callee.caller!=thisCallback)
return jsonQueue({nelist:0},this);
with(D){...}
$('#nelist').html(this.CTV.join(""));
$('#nelist table img').each(function(){
$(this).click(function(){
var ck=!$(this).next('input').attr('checked');
if (ck){
$(this).next('input').attr('checked','checked');
$(this).addClass('checkboxon');
}else{
$(this).next('input').removeAttr('checked');
$(this).removeClass('checkboxon');
}
}).click();
});
}
-->
<!---/*-Child nelist*/-->
<!--3:nicEditor的模块列表结束-->
可以看到,传统的平面化 在我这个例子了已经不复存在了.jCT重构语法为自由布局提供了可能.
顺序化 被 thisCallback (这个名词我还是不满意)彻底打破.
关于 thisCallback 到底是什么东西请看:
http://achun.iteye.com/blog/209575
http://achun.iteye.com/blog/210023
jsonQueue就是这种想法的一个实例:
//回调函数,保持原来的this指针 function thisCallback(func,thiss,args){ func.apply(thiss,args); } //jsonQuene合并细粒度队列回调 function jsonQueue(queue,thiss,ask){ if (ask){ var ask='确定执行这个操作么?'+(options.ask===true?'':options.ask); if(false==confirm(ask)) return false; } var func=arguments.callee.caller; var data=JSON.stringify(queue); (function (func,data){ jQuery.ajax({ url: R('/'), dataType:'json', data:data, type:'POST', error:function(xml){ alert('Error : actionQuene'); }, success:function(a){ thisCallback(func,thiss,[a]); } }); })(func,data); return false; }
其他信息参见
降低前后台业务逻辑上的耦合度,前后台细粒度数据通讯的方法
当然我这种用法有些极端(不必要),但怎么说呢.对于这个例子完全可以把3部分写到一起.不过我喜欢的开发形式.jCT和thisCallback为这种提供了可能.