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)); } });