doT.js模板引擎及基础原理

个人bolg地址


时至今日,基于后端JavaScript(Node.js)和MVC思想也开始流行起来。模板引擎是数据和页面分离工作中最重要的一环,在各大门户网站均有利用到模板引擎。

模板引擎有很多种,但是原理了解也是非常必要的。

什么是模板引擎,其根本原理就是将数据转换成“String”,再通过模板引擎抓取数据进行页面数据渲染。 

看一个例子

1 <script type="template" id="template">
2     <h2>
3       <a href="{{href}}">
4         {{title}}
5       </a>
6     </h2>
7     <img src="{{imgSrc}}" alt="{{title}}">
8   </script>

这样的方法类似Angular和Vue中双向数据绑定。 {{ XXXX }} 是需要进行替换的数据。

var data = [
    {
      title: "我是标题1",
      href: "我是链接1",
      imgSrc: "我是图片1.jpg"
    },
    {
      title: "我是标题2",
      href: "我是链接2",
      imgSrc: "我是图片2.jpg"
    }
  ];

可以通过replace和正则的方法进行替换导入。

replace方法:

template = document.querySelector('#template').innerHTML,
result = document.querySelector('.result'),
attachTemplateToData;
 
// 将模板和数据作为参数,通过数据里所有的项将值替换到模板的标签上(注意不是遍历模板标签,因为标签可能不在数据里存在)。
attachTemplateToData = function(template, data) {
        var i = 0,
            len = data.length,
            fragment = '';
 
        // 遍历数据集合里的每一个项,做相应的替换
        function replace(obj) {
            var t, key, reg;
       
       //遍历该数据项下所有的属性,将该属性作为key值来查找标签,然后替换
            for (key in obj) {
                reg = new RegExp('{{' + key + '}}', 'ig');
                t = (t || template).replace(reg, obj[key]);
            }
 
            return t;
        }
 
        for (; i < len; i++) {
            fragment += replace(data[i]);
        }
 
        return fragment;
    };
 
result.innerHTML = attachTemplateToData(template, data);

不用再次去特意设置变量名。  

 

 

doT.js模板引擎

1.   {{ = it.xxx }}  赋值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>   <!-- = 赋值-->
</head>
<body>
    <div id="interpolation"></div>
    <script id="interpolationtmpl" type="text/x-dot-template">  <!--script的ID是为了被doT模板引擎抓取语法和模板 type必须为该类-->
        <div>Hi {{=it.name}}!</div>  <!--it在模板里为数据源 it.name 等同于 dataInter.name -->
        <div>{{=it.age || ''}}</div> <!-- = 为赋值,如果不存在改数据,||'' 为空 -->
    </script>
</body>
<script src="./doT.js"></script>
<script src="./jquery.min.js"></script>

<script>
//定义数据源 var dataInter = {"name":"jake","age":31};
  // doT使用模板方法进行抓取script标签里的模板语法和布局
var interText = doT.template($("#interpolationtmpl").text());
  // 将数据赋值给id对应的div进行渲染。 $(
"#interpolation").html(interText(dataInter)); </script> </html>

2.   {{ for }}  循环

   语法:  {{ for var KEY in DATA {  }}
                {{= key }}
                {{  }  }}

  

<body>
    <div id="evaluation"></div>
    <script id="evaluationtmpl" type="text/x-dot-template">
    {{ for(var prop in it) { }}
        <div>KEY:{{= prop }}--------VALUE:{{= it[prop] }}</div><!--将值进行赋值循环-->
    {{ } }}
    </script>

</body>
<script src="./doT.js"></script>
<script src="./jquery.min.js"></script>

<script>
   var dataEval = {
"name":"Jake",
"age":31,
"interests":["basketball","hockey","photography"],"contact":{"email":"122@123.com","phone":"999999999"}
};
var evalText = doT.template($("#evaluationtmpl").text()); $("#evaluation").html(evalText(dataEval)); </script>

要注意 {{ for(var prop in it) { }}  ...  {{  } }}   为闭合标签,是为了让其中的模板进行输出,以及让{{ ... }} 的表达式进行执行。

可能这种语法很多小伙伴们看不懂,但是 改变一下

 for(var prop in it) {       
        <div>KEY:{{= prop }}--------VALUE:{{= it[prop] }}</div> <!--将循环进行赋值-->
     } 

把外面的花括号去掉了就能看懂了把。和上相比,只是将表达式都用双花括号包围起来,以便给doT模板引擎识别。
{{ for(var prop in it) { }}
        <div>KEY:{{= prop }}--------VALUE:{{= it[prop] }}</div><!--将值进行赋值循环-->
    {{ } }}

 

3.   {{~it.array:value:index}}  数组数据

 语法:
     {{~data.array :value:index }}
       ...
     

<body>
    <div id="arrays"></div>
    <script id="arraystmpl" type="text/x-dot-template">
        {{~it.array:value:index}}  <-- ~ 为循环数组it.data -->
            <div>{{= index+1 }}{{= value}}</div>   <!--index为下标,初始值为0 ,可以进行计算-->
        {{~}}
    </script>
</body>
<script src="./doT.js"></script>
<script src="./jquery.min.js"></script>

<script>
   var dataArr = {"array":["banana","apple","orange"]};
   var arrText = doT.template($("#arraystmpl").text());
   $("#arrays").html(arrText(dataArr));
</script>

 

 

 

4.   {{ = it.xxx }}  赋值

 语法:

      {{? }} if
      {{?? }} else if
      {{??}} else

<body>   
    <div id="condition"></div>
    <script id="conditionstmpl" type="text/x-dot-template">

        {{? !it.name }}<!--if有数据就跳过-->
            <div>Oh, I love your name, {{=it.name}}!</div>
        {{?? it.age === 1}}<!-- else if (age=31)执行此 -->
            <div>当前值为{{= it.age}}</div>
        {{?? !(it.age === 0)}}<!-- else if (age不为0)执行此 -->
            <div>Guess nobody named you yet!</div>
        {{?? !it.age == 0)}}<!-- 0本身为false  所有age为true 取反 -->
            <div>Guess nobody named you yet!</div>
        {{??}}
             You are {{=it.age}} and still dont have a name?
        {{?}}

    </script>
</body>
<script src="./doT.js"></script>
<script src="./jquery.min.js"></script>

<script>
    var dataEncode = {"name":"yzw","age":1};
    var EncodeText = doT.template($("#conditionstmpl").text());
    $("#condition").html(EncodeText(dataEncode));
</script>

提示:!it.age  当age为0的时候为true,非0为false,但是进行数据恒等(===)的时候,

如果想要将数据的结果进行取反,必须加个括号!(it.age === 0)  当age为0  ,为false  不等于!it.age === 0;

 

 

模板引擎还是非常好用的,其余的{{for 插值 with encoding }}、{{##}}就不在本文叙述了,在使用过程中至今还未使用到。

 

posted @ 2017-09-29 09:36  叶落偏执  阅读(3721)  评论(0编辑  收藏  举报