Handlebars模板库简单介绍

Handlebars是JavaScript一个语义模板库,通过对view(模板)和data(ajax请求的数据,一般是json)的分离来快速构建Web模板。它采用"Logic-less template"(无逻辑模版)的思路,在加载时被预编译(先对view进行编译生成模板,之后只要把json数据套进去就行了),而不是到了客户端执行到代码时再去编译,这样可以保证模板加载和运行的速度。Handlebars兼容Mustache,你可以在Handlebars中导入Mustache模板。

Handlebars expressions是handlebars模板中最基本的单元,使用方法是加两个花括号{{value}}, handlebars模板会自动匹配相应的数值,对象甚至是函数。

当你想要复用模板的一部分,或者将长模板分割成为多个模板方便维护时,partials就派上用场了。

通过{{}}取出来的内容(把json的数据取到后,显示在模板中时),都会经过编码,也就是说,如果取出的内容中包含html标签,会被转码成纯文本,不会被当成html解析,实际上就是做了类似这样的操作:把<用&lt;替代。这样做是很好的,既可以显示html代码(转码后的html),又可以避免xss注入(避免显示的内容是script,或者href,img等有跨站脚本攻击的标签)。这个功能在做代码展示的时候是非常有用的。但是有时候我们可能需要解析html,不要转码,很简单,把{{}}换成{{{}}}就可以啦。

Handlebars模板库简单使用

<!DOCTYPE html>
 <html>
   <head>
       <title>Handlebars Expressions Example</title>
   </head>
   <body>
       <h1>Handlebars Expressions Example!</h1>
       <div id="list">
       </div>

  <script type="text/javascript" src="script/jquery.js"></script>     //引入jquery插件
       <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>    //引入handlebars模板库

  <script id="people-template" type="text/x-handlebars-template">      //显示在页面上的标准模板
         {{#each people}}
      <div class="person">
                 <h2>{{first_name}} {{last_name}}</h2>
                 <div class="phone">{{phone}}</div>
                 <div class="email"><a href="mailto:{{email}}">{{email}}</a></div>
                 <div class="since">User since {{member_since}}</div>
           </div>
         {{/each}}
       </script>

  <script type="text/javascript">
           $(document).ready(function() {    //页面加载完成后,执行
    
               var template = Handlebars.compile($("#people-template").html());

         //先取到标准模板库的元素,然后调用html方法,得到它的内容。由于它的内容是一个handlebars模板,所以可以用Handlebars.compile对这个模板进行预编译。这里讲下jQuery对象html方法:$().html(),取第一个匹配元素的内容。$().html("chaojidan"),设置所有匹配元素的内容。$().html(function(index,content){  return newContent; }) ,index是匹配元素的位置,content是匹配元素的内容,newContent是替换匹配元素内容的新内容。

      var data = {   //后台通过ajax请求到的数据
                 people: [
                     { first_name: "Alan", last_name: "Johnson", phone: "1234567890", email: "alan@test.com", member_since: "Mar 25, 2011" },
                     { first_name: "Allison", last_name: "House", phone: "0987654321", email: "allison@test.com", member_since: "Jan 13, 2011" },
              { first_name: "Nick", last_name: "Pettit", phone: "9836592272", email: "nick@test.com", member_since: "Apr 9, 2009" },
                     { first_name: "Jim", last_name: "Hoskins", phone: "7284927150", email: "jim@test.com", member_since: "May 21, 2010" },
                     { first_name: "Ryan", last_name: "Carson", phone: "8263729224", email: "ryan@test.com", member_since: "Nov 1, 2008" }
                 ]
               };

      $('#list').html(template(data));   //把data对象传进去,模板会自动去匹配数据。模板中取得是data.people属性的值。并且对people循环处理,然后把people数组中的每一项进行输出。最后显示在页面中。
           });
       </script>
   </body>
 </html>

web 开发中,js 解析JSON 是经常的事情。非常繁琐。handlebars 使用了模版,只要你定义一个模版,提供一个json对象,handlebars 就能把json对象放到你定的模版中,非常方便好用!

在模板中也可以使用if语句,if 使用方法很简单,只需要在template中添加{{if}}, 如果有else,也一样,添加{{else}}。Template中代码如下:
 {{#each people}}      
   <div class="person">
     <p>{{title}}          
    {{#if author}}         //people数组中的每一项,如果有author属性,就进入if语句,显示以下html
            {{author.first_name}} {{author.last_name}}</p>
       {{else}}     //没有就显示以下html
            Unknown Author</p>
       {{/if}}
  </div>
{{/each}}

javascript模板引擎恰恰就是为了帮助我们有效的组织数据及其展示内容而出现的。和其它的模板使用方式一样,你需要做如下两个事情:
1. 创建展示模板      var myTemplate = Handlebars.compile($("#table-template").html());  $("#table-template").html()为模板内容

2. 将数据解析到模板中     $('#tableList').html(myTemplate(data));    myTemplate(data)为模板和数据生成的html

我们可以使用with块去定位我们需要的celebrity属性:

如果我们有一个这样的上下文对象:

var shoesData = {groupName:"Celebrities", celebrity:{firstName:"Mike", lastName:"Alexander" } };



<script id="shoe-template" type="x-handlebars-template">
  {{groupName}} Group
    {{#with celebrity}}    //进入到celebrity的上下文
      <li>{{firstName}} {{lastName}}</li>
    {{/with}}
</script>

下面的代码表明了怎样在Handlebars模板中添加注释:

{{! 在这其中的注释表达式不会被输出 }}
你也可使使用一般的HTML注释,但是它们会被输出到HTML页面源文件中,就像一般的HTML注释一样:

<!-- Regular HTML comments will be in the output -->

Handlebars可以使用../来查询当前上下文中的父路径的属性。比如,有一个数据对象如下:

var shoesData = {groupName:"Celebrities", users:[{name:{firstName:"Mike", lastName:"Alexander" }}, {name:{firstName:"John", lastName:"Waters" }} ]};

 
我们可以使用父路径 ../ 来得到groupName属性:

<script id="shoe-template" type="x-handlebars-template">
  {{#users}}     //此种方法也会把users数组中的每一项也输出
    <li>{{name.firstName}} {{name.lastName}} is in the {{../groupName}} group.</li>   //父路径下的groupName属性
  {{/users}}
</script>

unless辅助函数可以增强if,else。下面的代码意思:只有当userLoggedIn属性被检查为假值是其中的内容才会被渲染:

{{#unless userLoggedIn}} Please Log in. {{/unless}}


最后讲一下Handlebars最重要的使用方法:

Handlebars.js自定义辅助函数

Handlebars允许我们添加我们自己的自定义辅助函数,有了自定义辅助函数,我们可以添加任意的Javascript逻辑。我们需要在所有的Handlebars JS代码之前注册自定义辅助函数。自定义辅助函数在Javascript代码中被创建,而不是在Handlebars模板中。

你可以创建两种自定义辅助函数:自定义辅助函数(function helper),它不要使用块表达式就能运行,自定义块辅助函数,它需要和一个块表达式一起运行。

自定义函数辅助函数(function helper)

首先,我们必须用Handlebars.registerHelper方法注册一个自定义辅助函数。这个方法接收一个字符串(辅助函数的名字)作为第一个参数,一个具有任意参数个数的函数作为第二个参数。

Handlebars.registerHelper ("theNameOfTheHelper", function (theScore) {

  if (theScore >= 90) {
    return "A" ;
  }
  else if (theScore >= 80 && theScore < 90) {
    return "B" ;
  }
  else if (theScore >= 70 && theScore < 80) {
    return "C" ;
  }
  else {
    return "D" ;
  }

});

下面是一个使用我们刚才创建的自定义函数辅助函数的Handlebars模板:

<script id="shoe-template" type="x-handlebars-template">
  {{#theNameOfTheHelper score}}
</script>

下面是数据var contextObj = {score:85, userName:"Mike"};

最后,把score=85,传入到自定义函数中,返回B。于是模板最终结果返回一个"B"。

自定义块辅助函数

当我们注册了一个自定义块辅助函数时,Handlebars自动在回调函数中添加了一个可选择对象作为最后一个参数。这个可选择对象拥有一个fn方法,一个hash对象,以及一个inverse方法。fn方法接收一个对象(你的数据dataObject[i])作为自定义块表达式模板(<div>{{firstName}} {{lastName}}, Your Total Score is <strong>{{score}}</strong> </div>)中的上下文。你也可以传递任何数据对象,或者如果你想使用引用模板同样的上下文,你可以使用this(dataObject也就是contextObj)。

我们使用Handlebars.registerHelper注册一个userScore的块辅助函数。注意到参数中的最后一个项目是可选择对象,它由Handlebars自动添加:

Handlebars.registerHelper ("userScore", function (dataObject, options) {
  var templateWithInterpolatedData = "";

  for (var i = dataObject.length - 1; i >= 0; i--) {     //遍历dataObject数组
    dataObject[i].score = dataObject[i].score.reduce(function (prev, cur, index, array) {
      return prev + cur;      //数组中的每一项的score属性是一个数组,把这个数组的每一项相加,结果返回给score属性
    });  

    //这里我先介绍一下数组的reduce方法:reduce方法接受两个参数,一个回调方法,一个初始值。callback回调方法接受4个参数:之前值、当前值、索引值以及数组本身。initialValue(初始值)参数可选,表示初始值。若指定,则当作最初使用的previous值;如果缺省,则使用数组的第一个元素作为previous初始值,同时current往后排一位,相比有initialValue值少一次迭代。reduce方法,会把数组的每项进行迭代,最终的结果就是最后return的值。比如:var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {return previous + current;});因为没有初始值,所以previous就是数组的第一项,current就是数组的第二项,index值就是当前值的index(当前是1),array就是原数组[1,2,3,4]。第一次返回1+2=3,第二次previous等于上一次返回的值3,current等于当前值3,返回6,第三次previous等于6,当前值4,返回10.这时数组循环结束,把最后的返回结果10,返回给sum(数组调用reduce的结果)。 最终得到的结果就是数组的总和。

    // dataObject[i]变成了{firstName: "Kapil", lastName:"Manish", score:201}

    templateWithInterpolatedData += options.fn (c);

    //将会把对象的数据插入到模板中,也就是把{firstName: "Kapil", lastName:"Manish", score:201}插入到:<div>{{firstName}} {{lastName}}, Your Total Score is <strong>{{score}}</strong> </div>,最后叠加成一个字符串

    

  }

  return templateWithInterpolatedData;     //把所有的数据对象插入到模板后生成的html字符串返回。
});

数据:var contextObj = [{firstName: "Kapil", lastName:"Manish", score:[22, 34, 45, 67]}, {firstName: "Bruce", lastName:"Kasparov", score:[10, 34, 67, 90]}];

模板:

<script id="shoe-template" type="x-handlebars-template">
  {{#userScore this}}     //执行userScore(contextObj)
    <div>{{firstName}} {{lastName}}, Your Total Score is <strong>{{score}}</strong> </div>
  {{/userScore}}
</script>

最终的结果:

HTML的输出结果是:

Bruce Kasparov, Your Total Score is 201

Kapil Manish, Your Total Score is 168

options.inverse方法:

inverse方法在任意块表达式总被当做else部分来使用。因此,当回调函数中的表达式为一个真值是你可以使用options.fn来返回。但是当回调函数中的表达式为假值时你可以使用options.inverse(去渲染else部分中的内容)。

options.hash对象:

Handlebars表达式不接收任何字符串和变量作为参数,但是你依然可以传递用空格分开的键-值对。例如:

(注意到这里没有逗号来分开键-值对变量,是空格)

{{#myNewHelper score=30 firstName="Jhonny" lastName="Marco"}}
  Show your HTML content here.
{{/myNewHelper}}
调用拥有键-值对作为参数的Handlebars表达式将会自动添加到辅助函数回调函数的options.hash对象上。因此:

Handlebars.registerHelper ("myNewHelper", function (dataObject, options) {
  //JSON.stringify用于序列化一个json对象为一个字符串
  console.log(JSON.stringify (options.hash));
  //输出结果为:{score:30, firstName:"Jhonny", lastName:"Marco"}

});

加油!

转载于:https://www.cnblogs.com/chaojidan/p/4152866.html

Handlebars模板库浅析相关推荐

  1. Handlebars模板引擎

    介绍 Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板.它采用"Logic-less template"(无逻辑模 ...

  2. Handlebars模板引擎中的each用法(type=“text/x-handlebars-template“)

    ** handlebar ** 概述与介绍 Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板.它采用"Logic-less ...

  3. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

  4. C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)

    C++ 标准库可以分为两部分: 标准函数库: 这个库是由通用的.独立的.不属于任何类的函数组成的.函数库继承自 C 语言. 面向对象类库: 这个库是类及其相关函数的集合. C++ 标准库包含了所有的 ...

  5. 提高C++性能的编程技术笔记:标准模板库+测试代码

    标准模板库(Standard Template Library, STL)是容器和通用算法的强效组合. 渐近复杂度:算法的渐近复杂度是对算法性能的近似估计.它是算法集到特定性能标准集的映射.如果需要对 ...

  6. C++中标准模板库std::vector的实现

    以下实现了C++标准模板库std::vector的部分实现,参考了 cplusplus. 关于C++中标准模板库std::vector的介绍和用法可以参考 https://blog.csdn.net/ ...

  7. C++中标准模板库std::pair的实现

    以下用C++实现了标准模板库中的std::pair实现,参考了 cplusplus 和 vs2013中的utility文件. 关于std::pair的介绍和用法可以参考: https://blog.c ...

  8. STL 简介,标准模板库

    作者:Scott Field 这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL.     当我第一次打算写一篇关于STL的文章的 ...

  9. Part10 泛型程序设计与C++标准模板库 10.1泛型程序设计及STL的结构

    1泛型程序设计的基本概念 泛型程序设计: 编写不依赖于具体数据类型的程序 将算法从特定的数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 术语:概念 用来界定具备一定功能的数 ...

最新文章

  1. MFC libraries are required for this project. Install them from the Visual Studio installer (Individu
  2. python编程标准_python编程规范
  3. 学习小技巧---javascript中获取服务器端控件生成的页面ID
  4. Linux修改密码后不能SSH远程登录了
  5. 转:20分钟教你使用hexo搭建github博客
  6. 适用于苹果Mac的 5 个最佳 SSH 客户端软件
  7. 微信小程序列表项的右侧带箭头(非常简单)
  8. greenplum 数据库单机部署
  9. 计算机不识别固态硬盘,电脑经常不识别固态硬盘
  10. Conflux人物志-伍鸣博士:好奇心是我探索未知世界的动力
  11. 新中大软件ngpower6.1单机版安装流程(WIN11)
  12. 手机敬业签App怎么快速添加便签内容?
  13. 28岁程序员的2016规划
  14. 基于宜搭的《T恤尺码收集》应用搭建
  15. html隐藏标签属性
  16. 《MA‑CRNN: a multi‑scale attention CRNN for Chinese text line recognition in natural scenes》论文阅读
  17. 009 简单的渗透测试流程
  18. ET5.0 UGUI替换为FairyGUI
  19. android studio androidannotations,android studio 没有Annotation Processors 这个选项,求解答。...
  20. ES常用查询语法汇总

热门文章

  1. os.listdir的文件顺序与目录下文件顺序不一样
  2. 中国移动系统集成公司2020春招技术综合在线编程题第二题
  3. 全职宝妈跨专业备考信息系统项目管理师【52,52,51】
  4. Oracle 排序中使用nulls first 或者nulls last 语法
  5. simditor存储数据到前台展示去掉标签
  6. 软件项目管理0820:项目经理的困境
  7. 笔记-项目管理基础知识-项目管理办公室(PMO)
  8. CentOS7中离线安装Docker与卸载
  9. EleemntUI中el-table的formatter格式化字典显示的使用
  10. Winform中DevExpress的TreeList的入门使用教程(附源码下载)