JS页面模版引擎handlebars.js

示例在最后;
官网地址:http://handlebarsjs.com/
参考地址1:http://blog.csdn.net/fengqingtao2008/article/details/52711858
参考地址2:https://segmentfault.com/a/1190000008367747

1、如何引入Handlebars.js
首选要引入JQuery插件,其次在引用Handlebars.js即可,仅仅需要这两个js文件。

引入.png

2、基本语法
handlebarsjs 是模块中的最基本的单元,使用时用两个花括号{{ }} 包裹。eg:{{ value }} ,handlebars模块会自动匹配相应的数值,对象或者是函数。

<div class="demo">
    <h1>{{name}}</h1>
    <p>{{content}}</p>
</div>

也可以单独建立一个模板,id(或者class)可以用来唯一确定一个模板,type是固定写法,不可或缺。通过<script>标签包裹handlebars表达式传递模板给浏览器。

<script id="tpl" type="text/x-handlebars-template">
    <div class="demo">
            <h1>{{title}}</h1>
            <p>{{content.title}}</p>
    </div>
</script>

3、预编译模板
js 中使用handelbars.compile()预编译模板 :

//用jquery获取模板
var tpl   =  $("#tpl").html();
//原生方法
var source = document.getElementById('#tpl').innerHTML;
//预编译模板
var template = Handlebars.compile(source);
//模拟json数据
var context = { name: "zhaoshuai", content: "learn Handlebars"};
//匹配json内容
var html = template(context);
//输入模板
$(body).html(html);

通过解析context处理handlebars模板获取HTML内容:

var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);

输出html:

<div class="entry">
  <h1>My New Post</h1>
  <div class="body">
    This is my first post!
  </div>
</div>

4、blocks表达式

  • 表达式的后面跟一个#表示blocks;
  • 通过{{/表达式}}来结束Blocks;
  • 如果当前表达式是 数组则handelbars会展开数组。并将blocks的上下文设为数组元素);
<ul>
    {{#programme}}
        <li>{{language}}</li>
    {{/programme}}
</ul>

//对应json数据
 {
    programme: [
          {language: "JavaScript"},
          {language: "HTML"},
          {language: "CSS"}
          ]
 }

//渲染后:
<ul>
      <li>JavaScript</li>
      <li>HTML</li>
      <li>CSS</li>
</ul>

5、Handelbars内置表达式(Block helper)

  • each:
    利用{{#each name}}来遍历列表块的内容,
    用this来引用遍历的元素,指数组里的每一个元素。 name 是数组。
   <ul>
      {{#each name}}
        <li>{{this}}</li>
      {{/each}}
    </ul>

  //对应json是:
  {
    name: ["html","css","javascript"]
  };

  //编译后:
  <ul>
    <li>JavaScript</li>
    <li>HTML</li>
    <li>CSS</li>
  </ul>
  • if else :
    指定条件渲染dom;
    如果 {{ #if list }},即if后的参数存在, 则渲染{{ #else }}后面的语句;
    否则将不会渲染都dom,将执行{{ else }}后的error语句;
{{#if list}}
    <ul id="list">
        {{#each list}}
          <li>{{this}}</li>
        {{/each}}
    </ul>
    
{{else}}
      <p>{{error}}</p>
{{/if}}

//对应的json:
var data = {
    info:['HTML5','CSS3',"WebGL"],
    "error":"数据取出错误"
}
  • unless
    {{ #unless }}反向的一个if语句;unless后的参数 不存在 为false时,渲染dom;

  • with
    {{#with}}一般情况下,Handlebars模板会在编译的阶段的时候进行context传递 和 赋值。
    使用with的方法,我们可以将context转移到数据的一个section里面(如果你的数据包含section)。
    这个方法在操作复杂的template时候非常有用。
    即:在使用json数据较为复杂时,我们用这种方式来确定模板里填写的内容是json对象的哪一个部分!

 <div class="entry">
      <h1>{{title}}</h1>
        {{#with author}}
            <h2>By {{firstName}} {{lastName}}</h2>
        {{/with}}          
 </div>

//对应json数据:
{
    title: "My first post!",
    author: {
         firstName: "Charles",
         lastName: "Jolley"
     }
}

6、handlebar的注释(comments)
写法:

{{! handlebars comments }}

7、handlebar的访问(path)
可以通过 . 语法访问子属性;
也可以通过 ../ 来访问父级属性。

<h1>{{author.id}}</h1>
{{#with person}}
    <h1>{{../company.name}}</h1>
{{/with}}

8、自定义helper

用Handlebars.registerHelper ( )方法来注册一个helper

9、handelbars的jquery插件

(function($) {
      var compiled = {};
      $.fn.handlebars = function(template, data){
      if (template instanceof jQuery) {
          template = $(template).html();
  }
      compiled[template] = Handlebars.compile(template);
      this.html(compiled[template](data));
  };
})(jQuery);

$('#content').handlebars($('#template'), { name: "Alan" });

10、示例
(1)、each-基本循环使用方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Handlebars模板运用</title>
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
    <h1>each-基本循环使用方法</h1>
    <!--基础html框架-->
    <table>
        <thead>
            <tr>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody id="tableList">
        </tbody>
    </table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">
    {{#each student}}
    <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
    {{/each}}
</script>
<!--进行数据处理、html构造-->
<script type="text/javascript">
    $(document).ready(function() {
    //模拟的json对象
    var data = {
    "student": [
        {
        "name": "王五",
        "sex": "男",
        "age": 28
        },
        {
        "name": "李四",
        "sex": "女",
        "age": 30
        },
        {
        "name": "妞妞",
        "sex": "女",
        "age": 32
        }
    ]
    };
    //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架
    //$("#table-template").html()是jquery的语法。。。
    var myTemplate = Handlebars.compile($("#table-template").html());
    //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。
    $('#tableList').html(myTemplate(data));
    });
</script>

循环是Handlebars.js一个重要特性,#each可以理解成循环命令,循环的是json对象中的student属性。对于每次循环,都可以读出里边的name、sex、age属性。


each.png

(2)、each-循环中使用this

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Handlebars模板运用</title>
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
<h1>each-循环中使用this</h1>
<!--基础html框架-->
<table>
    <thead>
        <tr>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
        </tr>
    </thead>
    <tbody id="tableList">
    </tbody>
</table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">  
      {{#each this}}  
        <tr>  
            <td>{{name}}</td>  
            <td>{{sex}}</td>  
            <td>{{age}}</td>  
        </tr>  
        {{/each}}  
</script>  
<!--进行数据处理、html构造-->
<script type="text/javascript">  
   $(document).ready(function() {  
    //模拟的json对象  
       var data = [  
                   {  
                       "name": "张一",  
                       "sex": "男",  
                       "age": 28  
                   },  
                  {  
                      "name": "张二",  
                      "sex": "女",  
                      "age": 30  
                  },  
                   {  
                       "name": "张三",  
                       "sex": "女",  
                       "age": 32  
                   }  
                 ];  
     //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架  
     //$("#table-template").html()是jquery的语法。。。  
     var myTemplate = Handlebars.compile($("#table-template").html());  
     //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。  
    $('#tableList').html(myTemplate(data));  
    });  
</script>  

用#each this,表示遍历当前对象!this表示当前的上下文。


1.png

(3)、with-进入到某个属性(进入到某个上下文环境)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Handlebars模板运用</title>
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
 <h1>with-进入到某个属性(进入到某个上下文环境)</h1>  
        <!--基础html框架-->  
       <table>  
        <thead>  
            <tr>  
                <th>姓名</th>  
                <th>性别</th>  
                <th>年龄</th>  
                <th>兴趣爱好</th>  
            </tr>  
        </thead>  
        <tbody id="tableList">  
        </tbody>  
    </table>  
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">  
      {{#each this}}  
        <tr>  
            <td>{{name}}</td>  
            <td>{{sex}}</td>  
            <td>{{age}}</td>  
            <td>  
                 {{#with favorite}}  
                    {{#each this}}  
                        <p>{{name}}</p>  
                    {{/each}}  
                 {{/with}}  
            </td>  
        </tr>  
        {{/each}}  
</script>  
<!--进行数据处理、html构造-->
 <script type="text/javascript">  
   $(document).ready(function() {  
    //模拟的json对象  
       var data = [  
                   {  
                       "name": "张三丰",  
                       "sex": "男",  
                       "age": 28,  
                       "favorite":  
                       [  
                          {  
                            "name":"唱歌"  
                          },{  
                            "name":"篮球"  
                           }  
                       ]  
                   },  
                  {  
                      "name": "李妮妮",  
                      "sex": "女",  
                      "age": 30,  
                      "favorite":  
                      [  
                          {  
                              "name":"上网"  
                          },  
                           {  
                               "name":"足球"  
                          }  
                        ]  
                  },  
                   {  
                       "name": "王妞妞",  
                       "sex": "女",  
                       "age": 18,  
                      "favorite":  
                    [  
                      {  
                          "name":"电影"  
                      }, {  
                          "name": "旅游"  
                      }  
                  ]  
                 }  
                 ];  
     //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架  
     //$("#table-template").html()是jquery的语法。。。  
     var myTemplate = Handlebars.compile($("#table-template").html());  
     //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。  
    $('#tableList').html(myTemplate(data));  
 });  
</script>  
with

在循环每名学生时,学生的favorite属性并不是一个普通的字符串,而又是一个json对象,确切的说是一个数组,我们需要把学生的爱好全部取出来。

这时候就需要with命令,这个命令可以让当前的上下文进入到一个属性中,{{#with favorite}}表示进入到favorite属性的上下文中,而favorite属性中又是一个list,因此可以用{{#each this}}进行遍历,表示遍历当前上下文环境,对于每次遍历。

(4)、if-判断的基本用法+Helper方法

在遍历student时,由于数据缺失,并不是每一个学生都有name属性,我们不想显示没有name属性的学生,这时就需要if来做判断。

{{#if name}}可以用来判断当前上下文中有没有name属性,实际上,它是尝试去读取name属性,如果返回的为undefined、null、""、[]、false任意一个,都会导致最终结果为假。

其实,在Handlebars的模板标签中,{{#if condition}}{{/if}}只能判断这个condition是否为truefalse,并不能判断是否等于某个特定的值。
可以借助HandlebarsregisterHelper方法来实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Handlebars模板运用</title>
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
<h1>if-判断的基本用法+Helper方法</h1>
<!--基础html框架-->
<table>
    <thead>
        <tr>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
        </tr>
    </thead>
<tbody id="tableList"></tbody>
</table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
 <script id="table-template" type="text/x-handlebars-template">  
    {{#each student}}  
        {{#if name}}  
            {{#compare age 20}}  
                <tr>  
                    <td>{{name}}</td>  
                    <td>{{sex}}</td>  
                    <td>{{age}}</td>  
                </tr>  
        {{else}}  
                <tr>    
                    <td>?</td>  
                    <td>?</td>  
                    <td>?</td>  
                </tr>  
            {{/compare}}  
        {{/if}}  
    {{/each}}  
</script>  
<!--进行数据处理、html构造-->
 <script type="text/javascript">  
   $(document).ready(function() {  
    //模拟的json对象  
     var data = {  
                 "student": [  
                     {  
                      "sex": "男",  
                       "age": 18  
                   },  
                    {  
                         "name": "李四",  
                         "sex": "女",  
                        "age": 30  
                   },  
                     {  
                        "name": "妞妞",  
                         "sex": "女",  
                       "age": 32  
                     }  
                ]  
            };  
     //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架  
     //$("#table-template").html()是jquery的语法。。。  
     var myTemplate = Handlebars.compile($("#table-template").html());  
       //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。  
       //注册一个比较大小的Helper,判断v1是否大于v2  
       Handlebars.registerHelper("compare",function(v1,v2,options){  
          if(v1>v2){  
            //满足添加继续执行  
            return options.fn(this);  
          }else{  
            //不满足条件执行{{else}}部分  
            return options.inverse(this);  
          }  
         });  
    $('#tableList').html(myTemplate(data));  
 });  
</script>  
if

注:Handlebars.registerHelper用来定义Helper,它有两个参数,第一个参数是Helper名称,第二个参数是一个回调函数,用来执行核心业务逻辑。本例中的函数,有三个参数,其中前两个参数是需要比较的两个数,第三个参数是固定的,就叫options,如果加了该参数,就说明这个Helper是一个Block,块级别的Helper,有一定的语法结构,调用的时候加#号,就像if那样。

关于options的使用,return options.fn(this);表示满足条件继续执行,也就是执行{{#compare }}{{else}}之间的代码;return options.inverse(this);表示不满足条件,也就是执行{{else}}{{/compare}}之间的代码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352