這個是公司內部使用的一個模版引擎,主要應用在pc。
根據模版,返回一個js文件。大概是這個樣子的js。
(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賦值是模版引擎做的事情。
如果NodeTpl中的模版緩存中已經有了這個路徑了,那就直接取得,不然就需要再定義個對象出來。這個對象要包含整個模版文件中的不同模版對象。每個都是個方法。
通常是通過main主模版方法,在里面可能會用到子模版的方法。。。
傳給這些方法的有$data數據, 和guid(模版的id)。這里目前有個疑惑。。。
這個對象中有個template方法,在pc端根據不同瀏覽器確定是數組拼接還是字符串拼接,m端和以后就不需要這個了,直接字符串拼接就好。因為瀏覽器js引擎對字符串拼接做了優化,字符串更快。
這里除了guid,還用了dguid,是數據的id。
然后開始了css代碼的處理,其實就是每個前面都加上了模版對應都guid,對js也進行了封裝炒作,(怎么感覺做了很多不是模版引擎應該干的事情呢)
js添加的代碼如下:
'(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都做來處理,算是主要內容。這個主要內容大體就是正則替換
艾馬,這么一邊寫邊分析,果然比直接看代碼容易理解多了
