Handlebars详解使用

Handlebars详解使用

按照我个人习惯和学习的总结,最前面放完整代码是比较合适的,故先放出整个代码,后文再一点点讲解。

完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery-1.8.3.min.js"></script>
    <script src="../js/handlebars-v3.0.0.js"></script>
</head>
<body>
    <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}
    </script>
    <table border="1">
        <thead>
            <tr>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <script>
        var houdun={
            "student":[
                {
                   "name":'郝某人',
                   "sex":'男',
                   "age":21
                },
                {
                   "name":'杜哈哈',
                   "sex":'女',
                   "age":20
                },
                {
                   "name":'小郝',
                   "sex":'女',
                   "age":22
                }

            ]
        }
        var myTpl=Handlebars.compile($('#tbody-tr').html());
        $('tbody').html(myTpl(houdun));
   </script>
</body>
</html>

使用步骤:

第一步,导入jquery和handlebars的js文件

如果没有对应的文件,可以去我的资源下载,地址:https://download.csdn.net/download/qq_43518645/12664585

<script src="../js/jquery-1.8.3.min.js"></script>
<script src="../js/handlebars-v3.0.0.js"></script>

第二步,构造原始代码。如下

    <table border="1">
        <thead>
            <tr>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody>
          <tr>
              <td></td>
              <td></td>
              <td></td>
          </tr>
          <tr>
              <td></td>
              <td></td>
              <td></td>
          </tr>
          <tr>
              <td></td>
              <td></td>
              <td></td>
          </tr>
        </tbody>
    </table>

思考:这一块,tbody标签中的元素这么多,而且在实际成产中,tr标签到底有多少个,是不确定的,这种显示的写法明显是不合适的,所以在此引出循环,each,故下文,我们先说 handlebars中each的使用。

each的简单使用

结合上文思考,我们把代码改变为如下内容:

 <thead>
            <tr>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>

标签中的内容一会我们动态来渲染。

首先,我们模拟一个json数据,用来装配这些tr内容。

<script>
        var houdun={
            "student":[
                {
                   "name":'郝某人',
                   "sex":'男',
                   "age":21
                },
                {
                   "name":'杜哈哈',
                   "sex":'女',
                   "age":20
                },
                {
                   "name":'小郝',
                   "sex":'女',
                   "age":22
                }

            ]
        }
   </script>

动态的标签

<script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}
  </script>
 //注解:
         //<script type="text/x-handlebars-template" id="tbody-tr">
         //此处type类型一定要指定为text/x-handlebars-template 固定写法,注意一下。
         //id="tbody-tr"  起一个id,方便后面引入寻找。
// {{#each xxxx}}  xxxx填写的就是要遍历的元素,此处是要遍历模拟的json数据,即student
// {{name}} {{sex}} {{age}}  即取到student中的信息。

实际成产中为了解耦,降低代码耦合度,这种“动态的标签”不会写在当前页面html或者js中,都是独立写出去,再引入,如写入到tpl等等文件中,在此,为了演示方便,入门容易,就暂时写在同一个html或者js中了。在此说明。

上面都是为了代码做准备,其实handlebars中的each使用起来特别简单。

var myTpl=Handlebars.compile($('#tbody-tr').html());
$('tbody').html(myTpl(houdun));

Handlebars.compile() 方法取到内容,此处的Handlebars.compile($(’#tbody-tr’).html())取到的就是下面的内容

 {{#each student}}
       <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}

取到内容后,要把它装配到哪呢?所以需要指定装配一下$(‘tbody’).html(myTpl(houdun)) 此处一个细节需要注意一下,houdun参数需要传入,要不然json数据在哪来没有指定。装配好之后,相当与这样的。

<thead>
            <tr>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody>
    {{#each student}}
       <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}
        </tbody>

tbody中就有对应的dom节点,并可以读取到json数据,进行渲染。

效果图

在这里插入图片描述

each里的this使用

当json报文为下面这种的时候

var houdun=
            [
                {
                   "name":'郝某人',
                   "sex":'男',
                   "age":21
                },
                {
                   "name":'杜哈哈',
                   "sex":'女',
                   "age":20
                },
                {
                   "name":'小郝',
                   "sex":'女',
                   "age":22
                }

            ]

没有对象的名字,就是拿到一个数据,这个使用,遍历json数据只需要把改为this即可,即修改下面代码。

 {{#each this}}
       <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}

其余代码均不需要改动。

each里的嵌套使用

如果现在json报文为下面这种情况,我们想让数据这样显示:郝某人的爸爸,郝某人的妈妈,郝某人的女朋友,很显然这种情况是存在的,需要用两层each

        var houdun=[
                {
                   "name":'郝某人',
                   "info":["爸爸","妈妈","女朋友"]
                },
                {
                   "name":'杜哈哈',
                   "info":["哥哥","弟弟","男朋友"]
                },
                {
                   "name":'小郝',
                   "info":["爷爷","奶奶","小侄儿"]
                }

            ]

即需要这样的结构

 <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each this}}
          {{#each info}}
       <tr>
        <td>{{../name}}{{this}}</td> 
       </tr>
          {{/each}}
       {{/each}}
    </script>
         
 //可以看到{{../name}}  这个,做的很人性化,name为第一层循环的信息,放在了 第二层循环的位置,使用../退上去,还是很人性化的。
//{{../name}}的{{this}}  这个this 是因为可以看到  json报文  "info":["爸爸","妈妈","女朋友"]  也是因为没有名字,所以使用this

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery-1.8.3.min.js"></script>
    <script src="../js/handlebars-v3.0.0.js"></script>
</head>
<body>
    <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each this}}
          {{#each info}}
       <tr>
        <td>{{../name}}{{this}}</td> 
       </tr>
          {{/each}}
       {{/each}}
    </script>
    <table border="1">

    </table>
    <script>
        var houdun=[
                {
                   "name":'郝某人',
                   "info":["爸爸","妈妈","女朋友"]
                },
                {
                   "name":'杜哈哈',
                   "info":["哥哥","弟弟","男朋友"]
                },
                {
                   "name":'小郝',
                   "info":["爷爷","奶奶","小侄儿"]
                }

            ]
        
        var myTpl=Handlebars.compile($('#tbody-tr').html());
        $('table').html(myTpl(houdun));
   </script>
</body>
</html>

效果图

在这里插入图片描述

each里的index使用

现在,如果有如下需求:

 <tr> 
                <th>序号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>

需要遍历一下序号,怎么做呢?其实很简单,使用{{@index}}即可。

  <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       <tr>
        <td>{{@index}}</td>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}
    </script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Euvdvs1-1595842263861)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\1595821869052.png)]

可以看到索引下标是从0开始的,如果我们需要从1开始呢?这里呢,也提供了解决办法,我们只需要注册一个帮助模块即可。(我个人的理解,就是注册一个函数,调用这个函数就行)

 Handlebars.registerHelper("addOne",function(index,option){
            return parseInt(index)+1;
        })

//相当于addOne是自己命名的一个函数名字,我们使用这个函数触发即可。


<td>{{addOne @index}}</td>

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery-1.8.3.min.js"></script>
    <script src="../js/handlebars-v3.0.0.js"></script>
</head>
<body>
    <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       <tr>
        <td>{{addOne @index}}</td>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
       {{/each}}
    </script>
    <table border="1">
        <thead>
            <tr> 
                <th>序号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <script>
        var houdun={
            "student":[
                {
                   "name":'郝某人',
                   "sex":'男',
                   "age":21
                },
                {
                   "name":'杜哈哈',
                   "sex":'女',
                   "age":20
                },
                {
                   "name":'小郝',
                   "sex":'女',
                   "age":22
                }

            ]
        }
        var myTpl=Handlebars.compile($('#tbody-tr').html());
        Handlebars.registerHelper("addOne",function(index,option){
            return parseInt(index)+1;
        })
        $('tbody').html(myTpl(houdun));
   </script>
</body>
</html>

效果图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I2kL1ZLh-1595842263863)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\1595822215617.png)]

each里的if使用

现在有如下需求,json报文段有的没有name字段,如果没有name字段就不让展示。

 var houdun={
            "student":[
                {
                   "name":'郝某人',
                   "sex":'男',
                   "age":21
                },
                {
                   "name":'杜哈哈',
                   "sex":'女',
                   "age":20
                },
                {
                   "sex":'女',
                   "age":22
                }

            ]
        }

只需要加入if就行{{#if name}}

 <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       {{#if name}}
       <tr>
        <td>{{addOne @index}}</td>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
        {{/if}}
       {{/each}}
    </script>

完整代码不贴出来了,就加个if。看效果图。

在这里插入图片描述

each里的增强if使用(自定义)

这个在讲解index的使用其实使用过。

就是注册个函数,然后绑定使用函数即可。

 Handlebars.registerHelper("compare", function (v1, v2, options) {
            if (v1 > v2) {
                return options.fn(this);
            } else {
                return options.inverse(this);
            }
        })
//这里强调一下细节点:
Handlebars.registerHelper("compare", function (v1, v2, options) 
  1、 compare是自己起的名字,可以任意起名字,但是起什么名字,就用什么名字调用。
  2function (v1, v2, options)   v1,v2说明是传入2个参数,options参数应该是指定为块标签。(不确定,应该是)  块标签即为   不带options参数,为行级标签。
  3、 options.fn(this)  为固定写法,表明如果v1>v2 走if分支,对应的即为走
     <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
 4、 options.inverse(this)  为固定写法,表明如果v1<=v2 走else分支,对应的即为走
    <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>年龄不大于20</td>
    </tr>
 <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       {{#compare age 20}}
       <tr>
       
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
    </tr>
    {{else}}
    <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>年龄不大于20</td>
    </tr>
        {{/compare}}
       {{/each}}
    </script>
html代码调用处理

这个话题是说什么呢?假如有如下报文段。

 var houdun = {
            "student": [
                {
                    "name": '郝某人',
                    "sex": '男',
                    "age": 21,
                    "homePage": '<a href="https://www.baidu.com/">百度首页</a>'
                },
                {
                    "name": '杜哈哈',
                    "sex": '女',
                    "age": 20,
                    "homePage": '<a href="https://www.baidu.com/">百度首页</a>'
                },
                {
                    "name": '小郝',
                    "sex": '女',
                    "age": 22,
                    "homePage": '<a href="https://www.baidu.com/">百度首页</a>'
                }

            ]
        }
 <script type="text/x-handlebars-template" id="tbody-tr">
       {{#each student}}
       <tr>
        <td>{{name}}</td>
        <td>{{sex}}</td>
        <td>{{age}}</td>
        <td>{{homePage}}</td>
       </tr>
       {{/each}}
    </script>
    <table border="1">
        <thead>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>主页</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <script>

看下效果图:

在这里插入图片描述

这显然不是我们想要的,我们想要的是这种的

在这里插入图片描述

那是什么原因造成我们的代码没有展示呢?

其实是因为Handlebars为了安全起见,为了防止外部注入,把代码编译成了源码,这样展示的就是刚才的错误展示,但是有时候我们就是想要用这种超链接,那么怎么办呢?其实很简单

 <td>{{{homePage}}}</td>

这里用3{{{}}}即可,之前为2{{}}

需要注意的是:此处演示的是超链接,其实只要是h5有意义的标签都存在这个问题,比如

哈哈

,都可以使用3个{{{}}}来进行解决。

行级的helper的使用

如果有一段json报文如下:

 var houdun = {
            "student": [
                {
                    "name": '郝某人',
                    "sex": 1,
                    "age": 21,
                    "homePage": '<a href="https://www.baidu.com/">百度首页</a>'
                },
                {
                    "name": '杜哈哈',
                    "sex": 0,
                    "age": 20,
                    "homePage": '<a href="https://www.baidu.com/">百度首页</a>'
                },
                {
                    "name": '小郝',
                    "sex": 1,
                    "age": 22,
                    "homePage": '<a href="https://www.baidu.com/">百度首页</a>'
                }

            ]
        }

性别为0和1,1的时候为男,0的时候为女,那应该怎么做呢?其实之前讲过。

Handlebars.registerHelper("sexA", function (v) {
           if(v==1){
               return "男";
           }else if(v==0){
               return "女";
           }
        })


<td>{{sexA sex}}</td>

可以看到function (v)中没有options参数了,没有即为块标签,其实用法和之前说的一样,比较简单。

效果图

在这里插入图片描述

with的使用

with即为进入一个属性当中。

先有如下报文

 var houdun = {
            "student": [
                {
                    "name": '郝某人',
                    "sex": 1,
                    "age": 21,
                    "hobby":[
                        {
                            "name":'篮球'
                        },
                        {
                            "name":'排球'
                        },
                        {
                            "name":'乒乓球'
                        }
                    ]
                },
                {
                    "name": '杜哈哈',
                    "sex": 0,
                    "age": 20,
                    "hobby":[
                        {
                            "name":'篮球'
                        },
                        {
                            "name":'排球'
                        },
                        {
                            "name":'乒乓球'
                        }
                    ]
                },
                {
                    "name": '小郝',
                    "sex": 1,
                    "age": 22,
                    "hobby":[
                        {
                            "name":'篮球'
                        },
                        {
                            "name":'排球'
                        },
                        {
                            "name":'乒乓球'
                        }
                    ]
                }

            ]
        }

想显示如下效果图
在这里插入图片描述

应该怎么做呢?先用with进入hobby中,再使用each进行遍历

 <td>
            {{#with hobby}}
            {{#each this}}
            <p>{{name}}</p>
            {{/each}}
            {{/with}}
        </td>

其实不用with也行,使用each循环更简单,不过要知道with这个用法。

<td>
            {{#each hobby}}
            <p>{{name}}</p>
            {{/each}}
        </td>

以上就是所有。结束。今天是杜妹的生日,生日快乐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值