静文sophie

导航

 

这个是公司内部使用的一个模版引擎,主要应用在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都做来处理,算是主要内容。这个主要内容大体就是正则替换

艾马,这么一边写边分析,果然比直接看代码容易理解多了

posted on 2015-08-15 12:47  静文sophie  阅读(2577)  评论(0编辑  收藏  举报