zoukankan      html  css  js  c++  java
  • Handlebars.js入门教程

    概述

    刚接触前端的时候,师傅就给我推荐了Handlebars,自己也蛮喜欢它的语法。到现在,Handlebars都已经更新到3.0.3了,是时候重新过一遍文档了。

    引入

    要使用Handlebars,首先你得download,然后再页面引入,就像这样

    <script src="script/lib/jquery.js"></script>
    <script src="script/lib/handlebars.js"></script>
    

    如果你使用了模块化的管理工具,如requirejs、webpack、seajs,不用担心。Handlebars是支持amd、cmd规范的,使用就像这样

    var Handlebars=require('Handlebars');
    

    基本

    来一个简单的例子,向服务器发起了一个ajax请求获取了一个对象数组,要渲染到页面上。数据格式是这样的

    var data = [
        {
            name: 'xxx',
            age: 10
        },
        {
            name: 'zzz',
            age: 12
        },
        {
            name: 'yyy',
            age: 9
        }
    ];
    

    首先我们要建立一个模板结构,也就是我们的Html,为了展示和逻辑分离,我们不应该将模版内容放到js当中,先看下不好的做法:

    var $container = $('#container');//容器
    var content = '';
    
    data.forEach(function (item) {
        content += '<p>' + item.name + ':' + item.age + '</p>';
    });
    
    $container.html(content);
    

    当Html内容一多,各种单引号,双引号,可读性、结构性太差。维护起来将是我们开发的噩梦。
    使用Handlebars,首先我们将Html抽出来,就像用script标签包裹起来,放入我们当前的页面中,就像这样

    <body>
        <div id="container"></div>
        <script type="text/x-handlebars-template" id="template-user">{{#each this}}
                <p>{{name}}:{{age}}</p>
            {{/each}}</script>
        <script src="script/lib/jquery.js"></script>
        <script src="script/lib/handlebars.js"></script>
        <script src="script/my/basicuse.js"></script>
    </body>
    

    记得改变type类型,这样浏览器就不会把标签里的内容当作js执行。然后编写我们的代码

    var $container = $('#container');//容器
    var source = $('#template-user').html();//获取到html结构
    var template = Handlebars.compile(source);//编译成模板
    var html = template(data);//生成完成的html结构
    $container.html(html);//插入dom
    

    Handlebars的基本使用就如上了,用{{ }}输出内容。记住了

    模板最外层的this就是你调用template方法时传入的对象

    Block

    我们使用模板一般都是为了遍历对象结构,然后渲染到页面上。有人说了如果我就传递个字符串进去呢?直接

    $container.html(str);
    

    用JBM模板!使用模板最常用的就是if判断和each遍历了,下面来详细讲解。

    Handlebars的block都是这种{{#each}}{{/each}}的闭合结构

    if/unless

    if

    Handlebars的if判断只能判断true和false,没办法进行这种a===3的逻辑判断。它的设定就是如此,它认为逻辑判断的内容不应该出现在模板中。看个例子

    #template   
    {{#if isEdit}}
        <p>isEdit</p>
    {{/if}}{{#if email}}
        <p>{{email}}</p>
    {{/if}}{{#if num}}
        <p>{{num}}</p>
    {{/if}}   
    
    #数据
    var data = {
        isEdit: true,
        email: '',
        num: '0'
    };
    
    #页面效果
    isEdit
    0
    

    Handlebars if在判断前会做类型转换,如''、undefined、null、0、[]等都会被识别为false。而实际情况下我们都用数字来标识不同的状态,碰到这种数据我们需要预处理下,才能渲染哦。

    if else

    #template    
    {{#if isEdit}}
        <p>isEdit</p>
    {{else}}
        <p>isNotEdit</p>
    {{/if}}   
    
    #数据
    var data = {
        isEdit: false
    };
    
    #页面效果
    isNotEdit
    

    看看多分支是咋子写的

    #template   
    {{#if isEdit}}
        <p>isEdit</p>
    {{else if isRead}}
        <p>isNotEdit isRead</p>
    {{else}}
        <p>isNotRead</p>
    {{/if}}   
    
    #数据
    var data = {
        isEdit: false,
        isRead: false
    };
    
    #页面效果
    isNotRead
    

    unless

    作用刚好跟if相反,if是true的时候返回,unless是false的时候返回,看例子

    #template    
    {{#unless isEdit}}
        <p>isNotEdit</p>
    {{else unless isRead}}
        <p>isRead</p>
    {{else}}
        <p>isNotRead</p>
    {{/unless}}   
    
    #数据
    var data = {
        isEdit: true,
        isRead:true
    };
    
    #页面效果
    isNotRead
    

    each

    遍历数组

    #template
    {{#each this}}
        <p>{{this.name}}:{{this.age}}</p>
    {{else}}
        <p>no data</p>    
    {{/each}}
    
    #数据
    var data = [
        {
            name: 'yyy',
            age: 23
        },
        {
            name: 'zzz',
            age: 55
        }
    ];
    
    #页面效果
    yyy:23
    zzz:55
    

    each也支持else的判断。each里面的this是指向单个对象的,这个时候this可以省略不写,效果是一样的

    {{#each this}}
        <p>{{name}}:{{age}}</p>
    {{/each}}

    遍历数组的时候一般都会输出序号,怎么破?

    #template
    {{#each this}}
        <p>{{this.name}}:{{this.age}}</p>
    {{/each}}   
    
    #页面效果
    0 yyy:23
    1 zzz:55
    

    通过@index或者@key都可以获得序号,但是序号都是从0开始的,这个比较坑!如果要从1开始,得自己写个helper处理,真实日了狗了!

    遍历数组的需要判别是第一个还是最后一个怎么破?

    #template
    {{#each this}}
        <p>{{name}}:{{age}}{{#if @first}}first{{/if}}{{#if @last}}last{{/if}}</p>
    {{/each}}
    
    #页面效果
    yyy:23 first
    zzz:55 last
    

    通过@first和@last可以判断是否是数组的第一个或者最后一个。

    如果在加上@odd、@even就完美了!

    遍历对象

    真实的应用场景下,服务器很可能会返回一个map,就是js当中的对象,这个时候我们是不知道有哪些key的,如何遍历这个map呢?

    #template
    {{#each this}}
        <p>{{@key}}:{{this}}</p>
    {{/each}}
    
    #数据
    var data = {
        name: 'yyy',
        age: 23
    };
    
    #页面效果
    name:yyy
    age:23
    

    通过@key可以获取到对象的key名称。

    Html转义

    假想这样一个场景,通过ajax获取到了一段富文本内容,然后展示在页面中

    #template
    <div>{{richText}}</div>
    
    #数据
    var data = {
        richText: '<div>this is rich text</div>'
    };
    
    #页面效果
    <div>this is rich text</div>
    

    这个时候你肯定会想了,真实日了狗了,怎么原样输出了,没有解析成html啊。因为{{richText}}的输出默认转义Html,几乎所有的模板引擎输出默认都是转义Html的,避免xss攻击。如果你想避免转义,请这样用

    {{{richText}}}
    

    Helpers

    列表输出的时候,如果有时间字段,一般都需要格式化时间,拿到数据后我们还得处理

    #template
    {{#each this}}
        <p>{{name}}:{{addTime}}</p>
    {{/each}}
    
    #js
    var data = [
        {
            name: 'xxx',
            addTime: new Date()
        },
        {
            name: 'zzz',
            addTime: new Date()
        }
    ];
    
    data.forEach(function(item){
       item.addTime=moment(item.addTime).format('YYYY-MM-DD');
    });
    
    #页面效果
    xxx:2015-05-26
    zzz:2015-05-26
    

    换个页面碰到类似的情景,相同的代码又得写一面,冗余的代码太多了,不利于后期维护。怎么破?

    #template
    {{#each this}}
        <p>{{name}}:{{moment addTime}}</p>
    {{/each}}
    
    #js
    Handlebars.registerHelper('moment', function (date, options) {
        var formatStr = options.hash.format || 'YYYY-MM-DD';
        return new Handlebars.SafeString(moment(date).format(formatStr));
    });
    
    var data = [
        {
            name: 'xxx',
            addTime: new Date()
        },
        {
            name: 'zzz',
            addTime: new Date()
        }
    ];
    

    注册一个全局的moment,这样所有的时间格式化,都可以通过{{moment time}}调用,维护的成本大大降低。
    需要注意的是helper如{{moment arg1 arg2}}的形式最多添加两个参数可以被注册函数获取到,如果要添加多个参数,请使用hash的形式

    #template
    <p>{{query name 'arg2' hash1='hash1' hash2='hash2'}}</p>
    
    #数据
    Handlebars.registerHelper('query', function (arg1, arg2, options) {
        console.log('arg1:' + arg1);
        console.log('arg2:' + arg2);
        console.log(options.hash);
    });
    
    var data = {
        name: 'jacky'
    };
    
    #控制台
    $ arg1:jacky
    $ arg2:arg2
    $ Object {hash2: "hash2", hash1: "hash1"}
    

    Handlebars.SafeString就是不转义Html,如果想转义Html直接return内容即可。

    #template
    <p>{{safe}}</p>
    
    #js
    Handlebars.registerHelper('safe', function () {
       return new Handlebars.SafeString('<div>safe string</div>')
    });
    
    #页面效果
    safe string
    

    Partials

    共享同一个模板内容,后端渲染使用的比较多

    #template
    <p>{{> footer}}</p>
    
    #js
    Handlebars.registerPartial('footer', function () {
        return new Handlebars.SafeString('<div>This is footer</div>')
    });
    
    var data = {
        name: 'jacky'
    };
    
    #页面效果
    This is footer
    

    ../

    这样一个数据结构渲染到页面上

    #template
    {{#each company.prodList}}
        <p>{{prodName}}{{company.comName}}</p>
    {{/each}}
    
    #js
    var data = {
        company: {
            comName: '技术有限公司',
            prodList: [
                {
                    prodName: '产品1'
                },
                {
                    prodName: '产品2'
                }
            ]
        }
    };
    
    #页面效果
    产品1
    产品2
    

    等等好像有点不对劲啊,为啥没有公司名称呢?前面说到each里面的this都是指向单个对象的,{{prodName}} {{company.comName}}这种写法省略了this,还原下

    {{#each company.prodList}}
        <p>{{this.prodName}}{{this.company.comName}}</p>
    {{/each}}

    知道问题在哪里了吧。怎么破?

    {{#each company.prodList}}
        <p>{{prodName}}{{../company.comName}}</p>
    {{/each}}

    通过../回到each之外。下面来填另一个经典的坑

    #template
    <ul>
        {{#each this}}
            <li>
                <ul>
                    {{#each this}}
                        <li>{{@../index}}-{{@index}}{{this}}</li>
                    {{/each}}
                </ul>
            </li>
        {{/each}}
    </ul>
    
    #js
    var data = [
        ['aaa', 'bbb', 'ccc'],
        ['ddd', 'eee', 'fff']
    ];
    
    #页面效果
    0-0 aaa
    0-1 bbb
    0-2 ccc
    1-0 ddd
    1-1 eee
    1-2 fff
    

    代码链接

    Github

    参考

    Handlebars

    概述

    刚接触前端的时候,师傅就给我推荐了Handlebars,自己也蛮喜欢它的语法。到现在,Handlebars都已经更新到3.0.3了,是时候重新过一遍文档了。

    引入

    要使用Handlebars,首先你得download,然后再页面引入,就像这样

    1.  
      <script src="script/lib/jquery.js"></script>
    2.  
      <script src="script/lib/handlebars.js"></script>

    如果你使用了模块化的管理工具,如requirejs、webpack、seajs,不用担心。Handlebars是支持amd、cmd规范的,使用就像这样

    var Handlebars=require('Handlebars');
    

    基本

    来一个简单的例子,向服务器发起了一个ajax请求获取了一个对象数组,要渲染到页面上。数据格式是这样的

    1.  
      var data = [
    2.  
      {
    3.  
      name: 'xxx',
    4.  
      age: 10
    5.  
      },
    6.  
      {
    7.  
      name: 'zzz',
    8.  
      age: 12
    9.  
      },
    10.  
      {
    11.  
      name: 'yyy',
    12.  
      age: 9
    13.  
      }
    14.  
      ];

    首先我们要建立一个模板结构,也就是我们的Html,为了展示和逻辑分离,我们不应该将模版内容放到js当中,先看下不好的做法:

    1.  
      var $container = $('#container');//容器
    2.  
      var content = '';
    3.  
       
    4.  
      data.forEach(function (item) {
    5.  
      content += '<p>' + item.name + ':' + item.age + '</p>';
    6.  
      });
    7.  
       
    8.  
      $container.html(content);

    当Html内容一多,各种单引号,双引号,可读性、结构性太差。维护起来将是我们开发的噩梦。
    使用Handlebars,首先我们将Html抽出来,就像用script标签包裹起来,放入我们当前的页面中,就像这样

    1.  
      <body>
    2.  
      <div id="container"></div>
    3.  
      <script type="text/x-handlebars-template" id="template-user">
    4.  
      {{#each this}}
    5.  
      <p>{{name}}:{{age}}</p>
    6.  
      {{/each}}
    7.  
      </script>
    8.  
      <script src="script/lib/jquery.js"></script>
    9.  
      <script src="script/lib/handlebars.js"></script>
    10.  
      <script src="script/my/basicuse.js"></script>
    11.  
      </body>

    记得改变type类型,这样浏览器就不会把标签里的内容当作js执行。然后编写我们的代码

    1.  
      var $container = $('#container');//容器
    2.  
      var source = $('#template-user').html();//获取到html结构
    3.  
      var template = Handlebars.compile(source);//编译成模板
    4.  
      var html = template(data);//生成完成的html结构
    5.  
      $container.html(html);//插入dom

    Handlebars的基本使用就如上了,用{{ }}输出内容。记住了

    模板最外层的this就是你调用template方法时传入的对象

    Block

    我们使用模板一般都是为了遍历对象结构,然后渲染到页面上。有人说了如果我就传递个字符串进去呢?直接

    $container.html(str);
    

    用JBM模板!使用模板最常用的就是if判断和each遍历了,下面来详细讲解。

    Handlebars的block都是这种{{#each}}{{/each}}的闭合结构

    if/unless

    if

    Handlebars的if判断只能判断true和false,没办法进行这种a===3的逻辑判断。它的设定就是如此,它认为逻辑判断的内容不应该出现在模板中。看个例子

    1.  
      #template
    2.  
      {{#if isEdit}}
    3.  
      <p>isEdit</p>
    4.  
      {{/if}}
    5.  
      {{#if email}}
    6.  
      <p>{{email}}</p>
    7.  
      {{/if}}
    8.  
      {{#if num}}
    9.  
      <p>{{num}}</p>
    10.  
      {{/if}}
    11.  
       
    12.  
      #数据
    13.  
      var data = {
    14.  
      isEdit: true,
    15.  
      email: '',
    16.  
      num: '0'
    17.  
      };
    18.  
       
    19.  
      #页面效果
    20.  
      isEdit
    21.  
      0

    Handlebars if在判断前会做类型转换,如''、undefined、null、0、[]等都会被识别为false。而实际情况下我们都用数字来标识不同的状态,碰到这种数据我们需要预处理下,才能渲染哦。

    if else

    1.  
      #template
    2.  
      {{#if isEdit}}
    3.  
      <p>isEdit</p>
    4.  
      {{else}}
    5.  
      <p>isNotEdit</p>
    6.  
      {{/if}}
    7.  
       
    8.  
      #数据
    9.  
      var data = {
    10.  
      isEdit: false
    11.  
      };
    12.  
       
    13.  
      #页面效果
    14.  
      isNotEdit

    看看多分支是咋子写的

    1.  
      #template
    2.  
      {{#if isEdit}}
    3.  
      <p>isEdit</p>
    4.  
      {{else if isRead}}
    5.  
      <p>isNotEdit isRead</p>
    6.  
      {{else}}
    7.  
      <p>isNotRead</p>
    8.  
      {{/if}}
    9.  
       
    10.  
      #数据
    11.  
      var data = {
    12.  
      isEdit: false,
    13.  
      isRead: false
    14.  
      };
    15.  
       
    16.  
      #页面效果
    17.  
      isNotRead

    unless

    作用刚好跟if相反,if是true的时候返回,unless是false的时候返回,看例子

    1.  
      #template
    2.  
      {{#unless isEdit}}
    3.  
      <p>isNotEdit</p>
    4.  
      {{else unless isRead}}
    5.  
      <p>isRead</p>
    6.  
      {{else}}
    7.  
      <p>isNotRead</p>
    8.  
      {{/unless}}
    9.  
       
    10.  
      #数据
    11.  
      var data = {
    12.  
      isEdit: true,
    13.  
      isRead:true
    14.  
      };
    15.  
       
    16.  
      #页面效果
    17.  
      isNotRead

    each

    遍历数组

    1.  
      #template
    2.  
      {{#each this}}
    3.  
      <p>{{this.name}}:{{this.age}}</p>
    4.  
      {{else}}
    5.  
      <p>no data</p>
    6.  
      {{/each}}
    7.  
       
    8.  
      #数据
    9.  
      var data = [
    10.  
      {
    11.  
      name: 'yyy',
    12.  
      age: 23
    13.  
      },
    14.  
      {
    15.  
      name: 'zzz',
    16.  
      age: 55
    17.  
      }
    18.  
      ];
    19.  
       
    20.  
      #页面效果
    21.  
      yyy:23
    22.  
      zzz:55

    each也支持else的判断。each里面的this是指向单个对象的,这个时候this可以省略不写,效果是一样的

    1.  
      {{#each this}}
    2.  
      <p>{{name}}:{{age}}</p>
    3.  
      {{/each}}

    遍历数组的时候一般都会输出序号,怎么破?

    1.  
      #template
    2.  
      {{#each this}}
    3.  
      <p>{{this.name}}:{{this.age}}</p>
    4.  
      {{/each}}
    5.  
       
    6.  
      #页面效果
    7.  
      0 yyy:23
    8.  
      1 zzz:55

    通过@index或者@key都可以获得序号,但是序号都是从0开始的,这个比较坑!如果要从1开始,得自己写个helper处理,真实日了狗了!

    遍历数组的需要判别是第一个还是最后一个怎么破?

    1.  
      #template
    2.  
      {{#each this}}
    3.  
      <p>{{name}}:{{age}} {{#if @first}}first{{/if}} {{#if @last}}last{{/if}}</p>
    4.  
      {{/each}}
    5.  
       
    6.  
      #页面效果
    7.  
      yyy:23 first
    8.  
      zzz:55 last

    通过@first和@last可以判断是否是数组的第一个或者最后一个。

    如果在加上@odd、@even就完美了!

    遍历对象

    真实的应用场景下,服务器很可能会返回一个map,就是js当中的对象,这个时候我们是不知道有哪些key的,如何遍历这个map呢?

    1.  
      #template
    2.  
      {{#each this}}
    3.  
      <p>{{@key}}:{{this}}</p>
    4.  
      {{/each}}
    5.  
       
    6.  
      #数据
    7.  
      var data = {
    8.  
      name: 'yyy',
    9.  
      age: 23
    10.  
      };
    11.  
       
    12.  
      #页面效果
    13.  
      name:yyy
    14.  
      age:23

    通过@key可以获取到对象的key名称。

    Html转义

    假想这样一个场景,通过ajax获取到了一段富文本内容,然后展示在页面中

    1.  
      #template
    2.  
      <div>{{richText}}</div>
    3.  
       
    4.  
      #数据
    5.  
      var data = {
    6.  
      richText: '<div>this is rich text</div>'
    7.  
      };
    8.  
       
    9.  
      #页面效果
    10.  
      <div>this is rich text</div>

    这个时候你肯定会想了,真实日了狗了,怎么原样输出了,没有解析成html啊。因为{{richText}}的输出默认转义Html,几乎所有的模板引擎输出默认都是转义Html的,避免xss攻击。如果你想避免转义,请这样用

    {{{richText}}}
    

    Helpers

    列表输出的时候,如果有时间字段,一般都需要格式化时间,拿到数据后我们还得处理

    1.  
      #template
    2.  
      {{#each this}}
    3.  
      <p>{{name}}:{{addTime}}</p>
    4.  
      {{/each}}
    5.  
       
    6.  
      #js
    7.  
      var data = [
    8.  
      {
    9.  
      name: 'xxx',
    10.  
      addTime: new Date()
    11.  
      },
    12.  
      {
    13.  
      name: 'zzz',
    14.  
      addTime: new Date()
    15.  
      }
    16.  
      ];
    17.  
       
    18.  
      data.forEach(function(item){
    19.  
      item.addTime=moment(item.addTime).format('YYYY-MM-DD');
    20.  
      });
    21.  
       
    22.  
      #页面效果
    23.  
      xxx:2015-05-26
    24.  
      zzz:2015-05-26

    换个页面碰到类似的情景,相同的代码又得写一面,冗余的代码太多了,不利于后期维护。怎么破?

    1.  
      #template
    2.  
      {{#each this}}
    3.  
      <p>{{name}}:{{moment addTime}}</p>
    4.  
      {{/each}}
    5.  
       
    6.  
      #js
    7.  
      Handlebars.registerHelper('moment', function (date, options) {
    8.  
      var formatStr = options.hash.format || 'YYYY-MM-DD';
    9.  
      return new Handlebars.SafeString(moment(date).format(formatStr));
    10.  
      });
    11.  
       
    12.  
      var data = [
    13.  
      {
    14.  
      name: 'xxx',
    15.  
      addTime: new Date()
    16.  
      },
    17.  
      {
    18.  
      name: 'zzz',
    19.  
      addTime: new Date()
    20.  
      }
    21.  
      ];

    注册一个全局的moment,这样所有的时间格式化,都可以通过{{moment time}}调用,维护的成本大大降低。
    需要注意的是helper如{{moment arg1 arg2}}的形式最多添加两个参数可以被注册函数获取到,如果要添加多个参数,请使用hash的形式

    1.  
      #template
    2.  
      <p>{{query name 'arg2' hash1='hash1' hash2='hash2'}}</p>
    3.  
       
    4.  
      #数据
    5.  
      Handlebars.registerHelper('query', function (arg1, arg2, options) {
    6.  
      console.log('arg1:' + arg1);
    7.  
      console.log('arg2:' + arg2);
    8.  
      console.log(options.hash);
    9.  
      });
    10.  
       
    11.  
      var data = {
    12.  
      name: 'jacky'
    13.  
      };
    14.  
       
    15.  
      #控制台
    16.  
      $ arg1:jacky
    17.  
      $ arg2:arg2
    18.  
      $ Object {hash2: "hash2", hash1: "hash1"}

    Handlebars.SafeString就是不转义Html,如果想转义Html直接return内容即可。

    1.  
      #template
    2.  
      <p>{{safe}}</p>
    3.  
       
    4.  
      #js
    5.  
      Handlebars.registerHelper('safe', function () {
    6.  
      return new Handlebars.SafeString('<div>safe string</div>')
    7.  
      });
    8.  
       
    9.  
      #页面效果
    10.  
      safe string

    Partials

    共享同一个模板内容,后端渲染使用的比较多

    1.  
      #template
    2.  
      <p>{{> footer}}</p>
    3.  
       
    4.  
      #js
    5.  
      Handlebars.registerPartial('footer', function () {
    6.  
      return new Handlebars.SafeString('<div>This is footer</div>')
    7.  
      });
    8.  
       
    9.  
      var data = {
    10.  
      name: 'jacky'
    11.  
      };
    12.  
       
    13.  
      #页面效果
    14.  
      This is footer

    ../

    这样一个数据结构渲染到页面上

    1.  
      #template
    2.  
      {{#each company.prodList}}
    3.  
      <p>{{prodName}} {{company.comName}}</p>
    4.  
      {{/each}}
    5.  
       
    6.  
      #js
    7.  
      var data = {
    8.  
      company: {
    9.  
      comName: '技术有限公司',
    10.  
      prodList: [
    11.  
      {
    12.  
      prodName: '产品1'
    13.  
      },
    14.  
      {
    15.  
      prodName: '产品2'
    16.  
      }
    17.  
      ]
    18.  
      }
    19.  
      };
    20.  
       
    21.  
      #页面效果
    22.  
      产品1
    23.  
      产品2

    等等好像有点不对劲啊,为啥没有公司名称呢?前面说到each里面的this都是指向单个对象的,{{prodName}} {{company.comName}}这种写法省略了this,还原下

    1.  
      {{#each company.prodList}}
    2.  
      <p>{{this.prodName}} {{this.company.comName}}</p>
    3.  
      {{/each}}

    知道问题在哪里了吧。怎么破?

    1.  
      {{#each company.prodList}}
    2.  
      <p>{{prodName}} {{../company.comName}}</p>
    3.  
      {{/each}}

    通过../回到each之外。下面来填另一个经典的坑

    1.  
      #template
    2.  
      <ul>
    3.  
      {{#each this}}
    4.  
      <li>
    5.  
      <ul>
    6.  
      {{#each this}}
    7.  
      <li>{{@../index}}-{{@index}} {{this}}</li>
    8.  
      {{/each}}
    9.  
      </ul>
    10.  
      </li>
    11.  
      {{/each}}
    12.  
      </ul>
    13.  
       
    14.  
      #js
    15.  
      var data = [
    16.  
      ['aaa', 'bbb', 'ccc'],
    17.  
      ['ddd', 'eee', 'fff']
    18.  
      ];
    19.  
       
    20.  
      #页面效果
    21.  
      0-0 aaa
    22.  
      0-1 bbb
    23.  
      0-2 ccc
    24.  
      1-0 ddd
    25.  
      1-1 eee
    26.  
      1-2 fff

    代码链接

    Github

    参考

    Handlebars

  • 相关阅读:
    token的时限多长才合适?
    WebFTP安装说明
    维度表和事实表的区别
    互联网产品mysql数据库设计总结
    网络的介数中心性(betweenness)及计算方法
    python中的编码与解码
    增强学习Reinforcement Learning经典算法梳理3:TD方法
    Mybatis 参考
    防御CSRF、XSS和SQL注入攻击
    转:PriorityQueue
  • 原文地址:https://www.cnblogs.com/QDuck/p/12093312.html
Copyright © 2011-2022 走看看