一、前言
什麼是模板引擎,說簡單點,就是一個字符串有幾個變量待定。比如:
var tpl="Hei,my name is <%name%>,and I\'m <%age%> years old.";
通過模板殷勤函數把數據塞進去,
var data={
"name":"Miya Bai",
"age":"20"
};
var result=tplEngine(tpl,data);
//Hei,my name is Barret Lee,and I'm 20 years old.
那這玩意有什麼作用呢?其實他就是一個預處理器(processor),搞php開發的童鞋對Smarty必然熟悉,Smarty是一個php模板殷勤,tpl中待處理的字符通過數據匹配然後輸出相應的html代碼,加之比較給力的緩存技術,其速度和易用性是非常給力的!JS Template也是一樣的,我們的數據庫裏保存着數以千萬計的數據,而每一條數據都是通過同一種方式輸入,就拿上面的例子來說,我們不可能在數據庫裏存幾千條”Hei,my name…”,而是隻保存對應的name和age,通過模板輸出結果。
JS模板引擎應該做哪些事情?看看下面一串代碼:
var tpl='<%for(var i=0;i<this.posts.length;i++){'+
'var post=post[i];%>'+
'<% if(!post.expert){ %>'+
'<span>post is null</span>'+
'<% } else { %>'+
'<a href="#"><% post.expert %> at <% post.time %></a>'+
'<% } %>'+
'<% } %>'
一個基本的模板殷勤至少可以保證上面的代碼可以正常解析,如送入數據是:
var data={
posts:[
{
"expert":"content1",
"time":"yesterday"
},
{
"expert":"content2",
"time":"today"
},
{
"expert":"content 3",
"time":"tomorrow"
},{
"expert":"",
"time":"eee"
}
]
};
可以輸出:
<a href="#">content 1 at yesterday</a>
<a href="#">content 2 at today</a>
<a href="#">content 3 at tomorrow</a>
<span>post is null</span>
先戳這個demo看看。
下面就具體說說這個模板殷勤的原理是啥樣的。
二、JS模板引擎的實現原理
1.正則摳出要匹配的內容
針對這一串代碼,通過正則獲取內容
var tpl="Hei,my name is <%name%>,and I\'m <% age %> years old."
var data={
"name":"Barret Lee",
"age":"20"
};
最簡單的方式就是通過replace函數了:
var result=tpl.replace(/<%([^%>]+)%>/g,function(s0,s1){
return data[s1];
})
通過正則替換,我們很輕鬆的拿到了result,你可以去試試,他正式我們想要的結果。但是這裏又有了一個問題,改一下data和tpl,
var tpl="Hei,my name is <% name %>,and I\'m <% info.age %> years old";
var data={
"name":"Barret Lee",
"info":{"age":20}
};
再用上面的方式去獲取結果,呵呵,不行了吧~這裏[“info.age”]本身就是undefined,所以我們需要換一種方式來處理這個問題,那就是將它轉換成真正的JS代碼。如:
return 'Hei,my name is '+data.name+', and I\'m'+data.info.age+'years old.'
但是接着又有一個問題來了,當我們的代碼中出現for循環和if的時候,上面的轉換明顯是不起作用的,如:
var tpl='Posts:'+
'<% for(var i=0;i<post.length;i++){'+
'<a href="#"><% post[i].expert %></a>'+
'<% } %>'
如果繼續採用上面的代碼,得到的結果便是:
return 'Posts: '+
for(var i=0;i<post.length;i++){+
}