javascript/jquery模板引擎——Handlebars初体验

时间:2022-08-24 09:03:21

 Handlebars.js下载地址:http://handlebarsjs.com/

  最近自己在建一个站,采用完全的前后端分离的方式,现在正在做前端的部分。其中有项功能是需要ajax调用后端接口,返回json数据后要动态的插入数据。但是一开始我自己是用最"传统"的通过js拼接html字符串,然后再用jq插入到页面中的方式。比如说下面的这个例子,我要显示一个个人信息卡:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>Index</title>
 6         <script src="js/jquery.js"></script>
 7         <style>
 8  .person {
 9  font-size:40px;
10  float:left;
11  padding:20px;
12  margin:30px;
13  background-color:pink;
14             }
15         </style>
16     </head>
17     
18     <body>
19         <div class = "person" id="person_info">
20         </div>
21     </body>
22     
23     <script>
24         var data = { 25  name:'约翰莫里森', 26  home:'美国', 27  job:'摔跤手'
28  }; 29         
30         var str = ""; 31  str += "<div>姓名:" + data.name + "</div>"; 32  str += "<div>出生地:" + data.home + "</div>"; 33  str += "<div>职业:" + data.job + "</div>"; 34         
35  $('#person_info').html(str); 36     </script>
37 </html>

  这里我得用自己"手动"拼接html字符串,况且这只是一个极其简单的例子,如果标签之间的嵌套、属性复杂的话,这种方式写起来相当的麻烦,且标签间没有层次结构,可读性和维护性极差。

  后来偶然在个地方了解到了模板引擎,从此这种工作一下简便了许多! 先看下用Handlebars完成上面的例子是如何操作的:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>Handlebars</title>
 6         <script src="js/jquery.js"></script>
 7         <script src="js/handlebars.js"></script>
 8         <style>
 9  .person {
10  font-size:40px;
11  float:left;
12  padding:10px;
13  margin-left:30px;
14  background-color:pink;
15             }
16         </style>
17     </head>
18     
19     <body>
20         <div id = "person_info">
21             <div class = "person">
22                 <div>姓名:{{name}}</div>    
23                 <div>出生地:{{home}}</div>
24                 <div>职业:{{job}}</div>
25             </div>
26         </div>
27     </body>
28     
29     <script>
30         var data ={ 31  name:'约翰莫里森', 32  home:'美国', 33  job:'摔跤手'
34  }; 35         
36         var tmpl = $('#person_info').html();
37         
38         var func = Handlebars.compile(tmpl);
39         
40         var result = func(data);
41         
42  $('#person_info').html(result);
43     </script>
44     
45 </html>

  先从最下面的js代码讲起,核心代码就这四句:

1  var tmpl = $('#person_info').html(); 2  var func = Handlebars.compile(tmpl); 3  var result = func(data); 4         $('#person_info').html(result);

  第一行的 var tmpl = $('#person_info').html(); 就只是基本的jq语法;<body>中<div id="person_info">块中的就是html模板,这里取得了该div块下的html模板内容(对象tmpl)。此时如果用console.log(tmpl)打印该对象的话,得到的内容是

1             <div class = "person">
2                 <div>姓名:{{name}}</div>    
3                 <div>出生地:{{home}}</div>
4                 <div>职业:{{job}}</div>
5             </div>

  用两个大括号括起来的变量名会在后面 向函数传入数据(下面会提到) 时进行匹配。

 

  第二行 var func = Handlebars.compile(tmpl); 通过Handlebars的compile()对刚刚取得的html模板进行预编译,返回的是一个函数(现在对象func即为该函数)。

   var result = func(data); 这个函数带有一个参数,该参数为用以匹配模板用的数据。我这里事先写死一个数据对象data,然后传入该函数内。返回值是匹配好的html内容,打印出来就是 :

1             <div class = "person">
2                 <div>姓名:约翰莫里森</div>    
3                 <div>出生地:美国</div>
4                 <div>职业:摔跤手</div>
5             </div>

  最后用jq将内容插入到页面中: $('#person_info').html(result); 

 

  如果有多项数据需要展示,则需要用到{{#each this}}  {{/each}}。 语法类似标签,所以要注意别漏了闭合标签{{/each}}。 {{#each this}} ... {{/each}}中间的内容是模板。this 则是指传入函数的数据data。  用在实现上述例子的代码如下:

 1 <body>
 2         <div id = "person_info">
 3             {{#each this}}
 4             <div class = "person">
 5                 <div>姓名:{{name}}</div>
 6                 <div>出生地:{{home}}</div>
 7                 <div>职业:{{job}}</div>
 8             </div>
 9             {{/each}}
10         </div>
11     </body>
12     
13     <script>
14         var data =[{
15             name:'约翰莫里森',
16             home:'美国',
17             job:'摔跤手'
18         },
19         {
20             name:'Faker',
21             home:'韩国',
22             job:'英雄联盟职业选手'
23         }];
24         
25         var tmpl = $('#person_info').html();
26         var func = Handlebars.compile(tmpl);
27         var result = func(data);
28         $('#person_info').html(result);
29     </script>

 

 

  如果对象间所包含的数据域有个别不同,则需要分支语句进行判断  即{{#if xxx}} {/if}}。 用例如下:

  

 1 <body>
 2         <div id = "person_info">
 3             {{#each this}}
 4             <div class = "person">
 5                 <div>姓名:{{name}}</div>
 6                 <div>出生地:{{home}}</div>
 7                 <div>职业:{{job}}</div>
 8                 {{#if life}}
 9                   <div>生涯经历:</div>
10                     <ul>
11                     {{#each life}}
12                         <li>{{this}}</li>
13                     {{/each}}
14                     </ul>
15                 {{/if}}
16             </div>
17             {{/each}}
18         </div>
19     </body>
20     
21     <script>
22         var data =[{
23             name:'约翰莫里森',
24             home:'美国',
25             job:'摔跤手'
26         },
27         {
28             name:'Faker',
29             home:'韩国',
30             job:'英雄联盟职业选手',
31             life:['S3世界总冠军','S4世界总冠军','S5世界总冠军']
32         }];
33         
34         var tmpl = $('#person_info').html();
35         console.log(tmpl);
36         var func = Handlebars.compile(tmpl);
37         var result = func(data);
38         $('#person_info').html(result);
39     </script>

 

 

  最后再附上一篇关于Handlebars语法比较详细的介绍:http://www.ghostchina.com/introducing-the-handlebars-js-templating-engine/