這個是公司內部使用的一個模版引擎,主要應用在pc。css
根據模版,返回一個js文件。大概是這個樣子的js。html
(function(N, undefined){ var PATH = 'http://core.pc.lietou-static.com/tpls/common/plugins/localdata/city.js'; if(!N || !N._tpls) return false; N._tpls[PATH] = N._tpls[PATH] ||{......}; })(window.NodeTpl);
其實也就是傳入了全局的NodeTpl變量。而且給path賦值了。path賦值是模版引擎作的事情。node
若是NodeTpl中的模版緩存中已經有了這個路徑了,那就直接取得,否則就須要再定義個對象出來。這個對象要包含整個模版文件中的不一樣模版對象。每一個都是個方法。數組
一般是經過main主模版方法,在裏面可能會用到子模版的方法。。。瀏覽器
傳給這些方法的有$data數據, 和guid(模版的id)。這裏目前有個疑惑。。。
緩存
這個對象中有個template方法,在pc端根據不一樣瀏覽器肯定是數組拼接仍是字符串拼接,m端和之後就不須要這個了,直接字符串拼接就好。由於瀏覽器js引擎對字符串拼接作了優化,字符串更快。函數
這裏除了guid,還用了dguid,是數據的id。優化
而後開始了css代碼的處理,其實就是每一個前面都加上了模版對應都guid,對js也進行了封裝炒做,(怎麼感受作了不少不是模版引擎應該乾的事情呢)ui
js添加的代碼以下:this
'(function(window, document, undefined){\n'); template.push(' var $ROOT = $("#'+ guid +'");\n'); template.push(' var $TPLS = NodeTpl._tpls["'+ PATH +'"];\n'); template.push(' var $DATA = NodeTpl._data["'+ dguid +'"];\n');
進行了封裝,而且定義了三個變量,這三個變量用來做區分。
這個還有個require方法,能夠用來得到子模版的內容。解析require以後的代碼以下:
container.html($TPLS[\'view-hwgat\']($DATA, "'+ guid +'"));\n');
目前爲止,這個模版引擎實現的功能以下:
1 解析出模版自己
2 對css進行加id處理
3 對js封裝處理
4 要能夠經過require方法引入子模版,m端跟其餘插件方法衝突,應該會修改爲其餘名字。好比include
至此,模版要作的事情就明確了。
下面再看看模版引擎是怎麼實現的。
從入口開始看起:
window[moduleName].render = function (html, data, callback) {
var path = this.rguid(),
that = this,
cache = that._tpls;
if (typeof data === 'function') { callback = data, data = {}; } (new Function(renderTools.templete(path, renderTools.precompile(html))))(); typeof callback === 'function' && typeof cache[path] === 'object' && typeof cache[path].main === 'function' && callback.call(that, cache[path].main(data)); return that; };
先看底下,若是有callback,以及模版緩存會給你一個對象,而且這個對象的main方法是個函數,其實咱們解析出來正確的結果就是這個樣子的。就調用來callback方法,傳遞給nodetpl對象,以及模版main方法渲染後的片斷
再看如何生成對應的模版緩存對象。經過new Function方法。具體再看裏面的renderTools.templete方法。
這個方法幹什麼用的,代碼以下:
templete: function (path, tpl) { var html = "", tpls = []; .......... html += "(function(N, undefined){\n"; html += " var PATH = '" + path + "';\n"; html += " if(!N || !N._tpls) return false;\n"; html += " N._tpls[PATH] = N._tpls[PATH] ||\n{\n"; html += tpls.join(',\n'); html += '\n};'; html += "\n})(window.NodeTpl);"; return html; }
傳給它的是咱們的模版引擎renderid,以及對應的模版內容,裏面可能有多個子模版。 而後分別進行解析,這裏解析主要是生成方法,文件中的css,js,html處理都在precompile中完成了。最終返回的就是咱們的js文件。
這個path最終怎麼成路徑,目前還沒看出來。
這個tpl傳進去的就已是預編譯以後的來,調用來precompile方法,裏面又用到compile方法。主要就是對css,js, html都作來處理,算是主要內容。這個主要內容大致就是正則替換
艾馬,這麼一邊寫邊分析,果真比直接看代碼容易理解多了