Javascript:自己寫模板引擎
因為JS沒有提供“字串插入”和“多行字串”特性,傳統的拼湊字串容易出錯、效能不高和不容易理解代碼,為了應對這些問題,很多個人和團隊開發了模板引擎,現在主流的JS架構幾乎都提供此類功能了。模板引擎的實現方式有很多種,此處介紹一種簡單、靈活和強大的思路,該方式借鑒了 JSP(網頁伺服器最終將 JSP 頁面轉換為了 Servlet),編譯後會把模板轉換為一個方法。這個實現只是為團隊介紹模板引擎的原理,具體應用還需要選擇成熟的開源實現。實現 1 <!DOCTYPE html> 2 3 <html xmlns="http://www.w3.org/1999/xhtml"> 4 <head runat="server"> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <title></title> 7 </head> 8 <body> 9 </body>10 </html>11 <script id="test-tpl" type="text/template">12 start13 14 <# for(var i=0; i< items.length; i++) {#>15 <#= items[i].name #>16 <# } #>17 18 end19 </script>20 <script type="text/javascript">21 var Template = function (tpl) {22 var me = this;23 24 me.tpl = tpl;25 };26 27 Template.prototype.compile = function () {28 var me = this;29 30 var codes = [];31 codes.push("var results = [];");32 codes.push("with(context) {");33 34 var frags = me.tpl.split(/(<#=.+?#>)|(<#.+?#>)/);35 for (var i = 0; i < frags.length ; i++) {36 var frag = frags[i];37 38 if (!frag) {39 continue;40 }41 if (frag.indexOf("<#=") == 0) {42 codes.push("results.push(" + frag.substring(3, frag.length - 2) + ");");43 }44 else if (frag.indexOf("<#") == 0) {45 codes.push(frag.substring(2, frag.length - 2));46 }47 else {48 codes.push("results.push('" + frag.split('\n').join('\\n') + "');");49 }50 }51 52 codes.push("}");53 codes.push("return results.join('');");54 55 console.log(codes.join("\n"));56 me.compiledTplFun = new Function("context", codes.join("\n"));57 };58 59 Template.prototype.apply = function (context) {60 var me = this;61 62 if (!me.compiledTplFun) {63 me.compile();64 }65 66 return me.compiledTplFun(context);67 };68 69 var tpl = new Template(document.getElementById("test-tpl").innerHTML)70 71 console.log(tpl.apply({ items: [{ name: "dgw" }] }));72 </script>