Handlebars 模板引擎基本用法以及预编译模板JS文件的使用

发布日期 目录 Handlebars

Handlebars 模板引擎

百度百科这样解释模板:模板是将一个事物的结构规律予以固定化、标准化的成果,它体现的是结构形式的标准化

handlebars的出现,解决了远古时期,使用字符串拼接标签的尬局,而handlebars作为模板引擎,将html结构固化,数据以变量的形式代替,这样html更容易维护,开发更方便,这种开发模式也导致前端mvc框架的出现。

场景例子:
远古时期的查询列表的列表数据回显:

// 在ajax请求的返回结果里面
// 返回的数据结构为 data = ['张三','李四','王五']
var str = '';
for (var i = 0; i < data.length; i++) {
    str += '<tr>';
    str += '<td>' + data[i].name + '</td>';
    ...
    str += '</tr>';
}
$('#tbodyId').html(str);

近代时期handlebars的查询列表的列表数据回显:

// 在html页面里面先写一个handlebars模板
<script id="tbody-template" type="text/x-handlebars-template">
    {{#each this}}
    <tr>
        <td>{{name}}</td>
    </tr>
    {{/end}}
</script>
// 在ajax请求的返回结果里面
// 返回的数据结构为 data = ['张三','李四','王五']
var tbodyTemp = Handlebars.compile($('#tbody-template').html());
$('#tbodyId').html(tbodyTemp(data));

现在应该了解了handlebars的用处,现在看下具体用法。

官方网站:·http://handlebarsjs.com/
下载地址:点击下载

以下要点:
+ Handlebars模板是写在<script></script>标签里面的,并且要注明这个标签的类型type="text/x-handlebars-template
+ 变量是以{{}}双换括号来取值的
+ 使用思路:
1. 要先将模板编译为js语言:var tbodyTemp = Handlebars.compile($('#tbody-template').html())
2. 再使用返回的方法传入数据data来生成html:tbodyTemp(data)。传入的data可以是数组可以是对象
3. 最后放入页面的html页面对应的标签中:$('#tbodyId').html(tbodyTemp(data))
+ 支持结构语法,判断语法,不支持直接在双花括号中运算

下面主要看模板的写法:

循环结构each语法:

{{#each this}}      // 循环语句开始  this指向传入的数据结构 data => tbodyTemp(data)
<li>{{this}}</li>   // 要循环的html结构
{{/end}}            // 循环语句结束

提示:
1. 如果传入的数据结构是对象data = {names:['张三','李四','王五']},可以下面这样取{{#each names}},一般我们都取到数组后再传入js方法:tbodyTemp(data.names)
2. 如果传入的数据结构是数组对象,下面这样

data = [
    {
        name:'张三',
        age:23
    },
    {
        name:'李四',
        age:20
    }
]

下面这样取值:

<script id="tbody-template" type="text/x-handlebars-template">
{{#each this}}          // this 为 数组的每一个元素对象
<tr>
    <td>{{name}}</td>   // name 为this.name
    <td>{{age}}</td>    // age  为this.age
</tr>
{{/each}}
</script>

with语法:

width的用处是进入到某个属性(进入到某个上下文环境),比如我们的数组的每个对象元素还有数组,这时候就要使用with进入的子数组里面,然后在循环字数组

比如数据结构是这样的:

data = [
    {
        name:'张三',
        results:[
            {
                subject:'语文',
                result:99
            },
            {
                subject:'数学',
                result:100
            }
        ]
    }
]

这个时候循环子数组:

<script id="tbody-template" type="text/x-handlebars-template">
    {{#each this}}
    <tr>
        <td>{{name}}</td>
        {{#with results}}               // 进入子数组
            {{#each this}}              // 循环子数组
                <td>{{subject}}</td>    // 子数组每个对象的值
                <td>{{result}}</td>
            {{/each}}
        {{/with}}
    </tr>
    {{/each}}
</script>

if判断语法:

if 判断 没啥说的直接看代码:

/*
data = [
    {
        name:'张三',
    },
    {
        name:'李四',
        age:23
    }
]
*/
<script id="tbody-template" type="text/x-handlebars-template">
    {{#each this}}
    <tr>
        <td>{{name}}</td>
        {{#if age}}
            <td>{{age}}</td>
            {{else}}            // 这两行也可以不用写,直接判断age存在时显示内容
            <td>未知年龄</td>    // 这两行也可以不用写,直接判断age存在时显示内容
        {{/if}}
    </tr>
    {{/each}}
</script>

helper助手:

helper,可译为助手的意思,说白了就是帮助你来完成某些功能。

比如:
我想判断某个值等于1时才显示对应的标签结构,否则显示另外的标签结构;又或者我想把某个值格式化为2位小数显示等等

helper主要有两种用法:
1. 处理某个值的显示方式
2. 替代if功力不足,而使用的高级点的判断

处理某个值的显示方式

上面说了取值是用{{}}来取值,但是取到这个值我想格式化一下再显示出来,这个时候我们需要注册一个helper助手

// js中
Handlebars.registerHelper('formatNumber', function(value) {
 return value.toFixed(2);
});
// 模板中这样使用
<script id="tbody-template" type="text/x-handlebars-template">
    {{#each this}}
    <tr>
        <td>{{formatNumber amount}}</td>  //formatNumber为上面注册的helper
    </tr>
    {{/each}}
</script>
替代if功力不足,而使用的高级点的判断

if只能判断值存不存在,基本上没多大用处,这事我们就需要注册一个高级的判断helper助手

比如:我们想判断某个值等于1显示对应的结构,否则显示另外的结构

// js中
Handlebars.registerHelper("compare",function(v1,v2,options){
  if(v1 == v2){
    //满足添加继续执行
    return options.fn(this);        // 固定写法
  }else{
    //不满足条件执行{{else}}部分
    return options.inverse(this);   // 固定写法
  }
});
// js数据结构
data = [
    {
        name:'张三',
        age:23,
        isDelete:1
    },
    {
        name:'李四',
        age:23,
        isDelete:0
    }
]
// 模板中这样使用
<script id="tbody-template" type="text/x-handlebars-template">
    {{#each this}}
    <tr>
        <td>{{name}}</td>
        {{#compare isDelete 1}}
            <td>该人已被删除</td>
        {{else}}
            <td>存在,年龄为{{age}}</td>
        {{/compare}}
    </tr>
    {{/each}}
</script>

当然我们也可以定义一个通用的compare判断助手

var operators = {
  '==':     function(l, r) {return l == r; },
  '===':    function(l, r) {return l === r; },
  '!=':     function(l, r) {return l != r; },
  '!==':    function(l, r) {return l !== r; },
  '<':      function(l, r) {return l < r; },
  '>':      function(l, r) {return l > r; },
  '<=':     function(l, r) {return l <= r; },
  '>=':     function(l, r) {return l >= r; },
  'typeof': function(l, r) {return typeof l == r; }
};

Handlebars.registerHelper('compare', function(left, operator, right, options) {
  if (arguments.length < 3) {
    throw new Error('Handlerbars Helper "compare" 需要3个参数');
  }

  if (!operators[operator]) {
    throw new Error('Handlerbars Helper "compare" 不存在的操作符:' + operator);
  }

  var result = operators[operator](left, right);

  if (result) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});

Handlebars预编译模板js引入用法:

采用Handlebars预编译模板js,可以不用handlebars.js文件,这时可以引入一个更小的文件handlebars.runtime.js,当然也可以引入handlebars.js,不冲突下面。说下这种用法:

1、首先我们需要在本地全局安装handlebars,使用nodejs包管理器来安装npm install -g handlebars
2、建立模板文件list,并在里面写入html模板内容,注意此时不用在写<script>标签了
3、使用handlebars命令来编译模板文件handlebars list -f list.js
4、在页面中引入list.js文件
5、通过js来调用编译后的jsvar html = Handlebars.templates.list(data)

发表评论

邮箱地址不会被公开。