artTemplate(点击打开链接)是一个Javascript模板引擎。用模板才渲染ajax请求获得的数据 ,要比用一些操作dom的JsApi优雅一些。性能应该也好很多。
然而我发现使用模板进行一些分支或判断的时候,往往会使模板看起来比较混乱。
例如有如下数据 [ {name:'aaa',status:1} ,{name:'bbb',status:0} ....]
按照官网的示例,模板需要这么写
<span style="white-space:pre"></span><script type="text/html" id="test-ugly-tpl">
{{each com as value index}}
<span>{{value.name}}</span>
{{if value.status==1}}
<p>正常</p>
{{else}}
<p>异常</p>
{{/if}}
{{/each}}
</script>
这还是比较简单的情况,实际使用中可能有多处分支,嵌套分支的情况。
虽然官网上没有写,但是经过本人的试验,发现artTemplate的语法是支持三目运算的
于是可以改进成下列代码
<span style="white-space:pre"></span><script type="text/html" id="test-ok-tpl">
{{each com as value index}}
<span>{{value.name}}</span>
<p>{{value.status==1?"正常":"异常"}}</p>
{{/each}}
</script>
这样一定程度上使代码的可读性变好了,但是如果是3种或以上的分支,嵌套三目运算又会影响代码的工整性。
于是我想为什么不把数据整理好,再进行模板渲染呢?如
<span style="white-space:pre"></span>for(var i in data){
if(data[i].status==1){
data[i].statusText="正常";
}else{
data[i].statusText="异常";
}
}
那么模板写起来就简单多了, 也实现了 运算逻辑与视图的分离.
<span style="white-space:pre"></span><script type="text/html" id="test-pretty-tpl">
{{each com as value index}}
<span>{{value.name}}</span>
<p>{{value.statusText}}</p>
{{/each}}
</script>
但是这样做,在渲染时进行了一次遍历操作,渲染中又进行了一次遍历,可能会使效率变差么?
经过实验,发现用第一种方式渲染300条数据,5-6纳秒。第二种和第三种为2-3纳秒。
测试代码如下:
由此可见,虽然多进行了一次遍历。但渲染遍历的时候工作减少了,效率反而提升了。
所以我推荐在开发过程中,现将需要渲染的数据进行初步的整理,在进行模板渲染的工作。
<span style="white-space:pre"></span>$(function(){
var data ;
$.post(
"someurl",
someParam,
function(res){
data=res.data;
renderUgly(data);
renderOk(data);
renderPretty(data);
}
);
function renderUgly(data){
var start = new Date().getTime();
$('#ugly').html(template('test-ugly-tpl',{com:data}));
var end = new Date().getTime();
console.log("render using ugly:"+(end-start));
}
function renderOk(data){
var start = new Date().getTime();
$('#ok').html(template('test-ok-tpl',{com:data}));
var end = new Date().getTime();
console.log("render using ok:"+(end-start));
}
function renderPretty(data){
var start = new Date().getTime();
for(var i in data){
if(data[i].status==1){
data[i].statusText="正常";
}else{
data[i].statusText="异常";
}
}
$('#pretty').html(template('test-pretty-tpl',{com:data}));
var end = new Date().getTime();
console.log("render using pretty:"+(end-start));
}
});