Handlerbars基础笔记
此笔记摘抄于杨元的博客(http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html)
引入
<script type="text/javascript" src="script/jquery.js"></script> <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
使用each循环
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <META http-equiv=Content-Type content="text/html; charset=utf-8"> 5 </head> 6 <body> 7 <!--基础html框架--> 8 <table> 9 <thead> 10 <tr> 11 <th>姓名</th> 12 <th>性别</th> 13 <th>年龄</th> 14 </tr> 15 </thead> 16 <tbody id="tableList"> 17 18 </tbody> 19 </table> 20 21 <!--插件引用--> 22 <script type="text/javascript" src="script/jquery.js"></script> 23 <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script> 24 25 <!--Handlebars.js模版--> 26 <!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句--> 27 <!--id可以用来唯一确定一个模版,type是模版固定的写法--> 28 <script id="table-template" type="text/x-handlebars-template"> 29 {{#each people}} 30 <tr> 31 <td>{{name}}</td> 32 <td>{{sex}}</td> 33 <td>{{age}}</td> 34 </tr> 35 {{/each}} 36 </script> 37 38 <!--进行数据处理、html构造--> 39 <script type="text/javascript"> 40 $(document).ready(function() { 41 //模拟的json对象 42 var data = { 43 "people": [ 44 { 45 "name": "Larry", 46 "sex": "0", 47 "age": 18 48 }, 49 { 50 "name": "Jack", 51 "sex": "0", 52 "age": 22 53 }, 54 { 55 "name": "Devin", 56 "sex": "1", 57 "age": 18 58 } 59 ] 60 }; 61 62 //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 63 var myTemplate = Handlebars.compile($("#table-template").html()); 64 65 //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 66 $('#tableList').html(myTemplate(data)); 67 }); 68 </script> 69 </body> 70 </html>
循环模板的那个地方有点像angularJS有木有?
还可以使用this,但是得做点修改
模板改用this
<!--id可以用来唯一确定一个模版,type是模版固定的写法--> <script id="table-template" type="text/x-handlebars-template"> {{#each this}} <tr> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> </tr> {{/each}} </script>
上面的data是个对象,现在得改用数组
<!--进行数据处理、html构造--> <script type="text/javascript"> $(document).ready(function() { //模拟的json对象 var data = [ { "name": "Larry", "sex": "0", "age": 18 }, { "name": "Jack", "sex": "0", "age": 22 }, { "name": "Devin", "sex": "1", "age": 18 } ]; //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 //$("#table-template").html()是jquery的语法,不懂的童鞋请恶补。。。 var myTemplate = Handlebars.compile($("#table-template").html()); //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 $('#tableList').html(myTemplate(data)); }); </script>
嵌套和循环更配噢!
1 <script id="table-template" type="text/x-handlebars-template"> 2 {{#each this}} 3 {{#each info}} 4 {{../name}}的{{this}}<br> 5 {{/each}} 6 {{/each}} 7 </script> 8 9 <!--进行数据处理、html构造--> 10 <script type="text/javascript"> 11 $(document).ready(function() { 12 //模拟的json对象 13 var data = [{ 14 "name":"Larry", 15 "info":[ 16 "test1", 17 "test2", 18 "test3" 19 ] 20 },{ 21 "name":"Devin", 22 "info":[ 23 "test4", 24 "test5", 25 "test6" 26 ] 27 }]; 28 29 //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 30 //$("#table-template").html()是jquery的语法,不懂的童鞋请恶补。。。 31 var myTemplate = Handlebars.compile($("#table-template").html()); 32 33 //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 34 $('#dataList').html(myTemplate(data)); 35 }); 36 </script>
既然有循环,肯定就会有index索引啦!
<!--id可以用来唯一确定一个模版,type是模版固定的写法--> <script id="table-template" type="text/x-handlebars-template"> {{#each student}} <tr> <td>{{testIndex @index}}</td> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> </tr> {{/each}} </script>
testIndex是变量,下面的registerHelper()要拎清楚
<script type="text/javascript"> $(document).ready(function() { //模拟的json对象 var data = { "student": [ { "name": "Larry", "sex": "0", "age": 18 }, { "name": "Jack", "sex": "0", "age": 22 }, { "name": "Devin", "sex": "1", "age": 19 } ] }; //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 //$("#table-template").html()是jquery的语法,不懂的童鞋请恶补。。。 var myTemplate = Handlebars.compile($("#table-template").html()); //注册一个Handlebars Helper,用来将索引+1,因为默认是从0开始的 Handlebars.registerHelper("testIndex",function(index,options){ return parseInt(index)+1; }); //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 $('#tableList').html(myTemplate(data)); }); </script>
访问父级索引,就是我们平时看目录看到的1.1 1.2 1.3 1.1.1 1.1.2 1.1.3这样的,怎么办?如下可破
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <META http-equiv=Content-Type content="text/html; charset=utf-8"> 5 <title>Handlebars.js循环中索引(@index)使用技巧 - by 杨元</title> 6 </head> 7 <body> 8 <h1>Handlebars.js循环中索引(@index)使用技巧</h1> 9 <!--基础html框架--> 10 <table> 11 <thead> 12 <tr> 13 <th></th> 14 <th>姓名</th> 15 <th>性别</th> 16 <th>年龄</th> 17 </tr> 18 </thead> 19 <tbody id="tableList"> 20 21 </tbody> 22 </table> 23 24 <!--插件引用--> 25 <script type="text/javascript" src="script/jquery.js"></script> 26 <script type="text/javascript" src="script/handlebars-v1.3.0.js"></script> 27 28 <!--Handlebars.js模版--> 29 <!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句--> 30 <!--id可以用来唯一确定一个模版,type是模版固定的写法--> 31 <script id="table-template" type="text/x-handlebars-template"> 32 {{#each this}} 33 <tr> 34 <td>{{addOne @index}}</td> 35 <td>{{name}}</td> 36 <td>{{sex}}</td> 37 <td>{{age}}</td> 38 </tr> 39 {{#each family}} 40 <tr> 41 <td>{{../_index}}.{{@index}}</td> 42 <td>{{name}}</td> 43 <td>{{sex}}</td> 44 <td>{{age}}</td> 45 </tr> 46 {{/each}} 47 {{/each}} 48 </script> 49 50 <!--进行数据处理、html构造--> 51 <script type="text/javascript"> 52 var data = [{ 53 name: "张三", 54 sex: "男", 55 age: 35, 56 family: [{ 57 name: "张三儿子", 58 sex: "男", 59 age: 10, 60 },{ 61 name: "张三妻子", 62 sex: "女", 63 age: 33, 64 }] 65 },{ 66 name: "李四", 67 sex: "男", 68 age: 23, 69 family: [{ 70 name: "李四妻子", 71 sex: "女", 72 age: 23, 73 }] 74 },{ 75 name: "甜妞", 76 sex: "女", 77 age: 18, 78 family: [{ 79 name: "甜妞妈妈", 80 sex: "女", 81 age: 40, 82 },{ 83 name: "甜妞爸爸", 84 sex: "男", 85 age: 43, 86 },{ 87 name: "甜妞姥爷", 88 sex: "男", 89 age: 73, 90 }] 91 }]; 92 93 //注册索引+1的helper 94 var handleHelper = Handlebars.registerHelper("addOne",function(index){ 95 //利用+1的时机,在父级循环对象中添加一个_index属性,用来保存父级每次循环的索引 96 this._index = index+1; 97 //返回+1之后的结果 98 return this._index; 99 }); 100 //解析模版 101 var handle = Handlebars.compile($("#table-template").html()); 102 //生成html 103 var html = handle(data); 104 //插入到页面 105 $("#tableList").append(html); 106 107 </script> 108 </body> 109 </html>
当你有好多个兴趣爱好的时候,要将它们罗列出来,但是这些兴趣爱好本身就是一个对象数组,也要被循环出来,怎么破?with这个时候就可以帮上忙了,它可以让你进入一个具体的上下文。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <META http-equiv=Content-Type content="text/html; charset=utf-8"> 5 <title>with-进入到某个属性(进入到某个上下文环境) - by 杨元</title> 6 </head> 7 <body> 8 <h1>with-进入到某个属性(进入到某个上下文环境)</h1> 9 <!--基础html框架--> 10 <table> 11 <thead> 12 <tr> 13 <th>姓名</th> 14 <th>性别</th> 15 <th>年龄</th> 16 <th>兴趣爱好</th> 17 </tr> 18 </thead> 19 <tbody id="tableList"> 20 21 </tbody> 22 </table> 23 24 <!--插件引用--> 25 <script type="text/javascript" src="script/jquery.js"></script> 26 <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script> 27 28 <!--Handlebars.js模版--> 29 <!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句--> 30 <!--id可以用来唯一确定一个模版,type是模版固定的写法--> 31 <script id="table-template" type="text/x-handlebars-template"> 32 {{#each this}} 33 <tr> 34 <td>{{name}}</td> 35 <td>{{sex}}</td> 36 <td>{{age}}</td> 37 <td> 38 {{#with favorite}} 39 {{#each this}} 40 <p>{{name}}</p> 41 {{/each}} 42 {{/with}} 43 </td> 44 </tr> 45 {{/each}} 46 </script> 47 48 <!--进行数据处理、html构造--> 49 <script type="text/javascript"> 50 $(document).ready(function() { 51 //模拟的json对象 52 var data = [ 53 { 54 "name": "张三", 55 "sex": "0", 56 "age": 18, 57 "favorite": 58 [ 59 { 60 "name":"唱歌" 61 },{ 62 "name":"篮球" 63 } 64 ] 65 }, 66 { 67 "name": "李四", 68 "sex": "0", 69 "age": 22, 70 "favorite": 71 [ 72 { 73 "name":"上网" 74 },{ 75 "name":"足球" 76 } 77 ] 78 }, 79 { 80 "name": "妞妞", 81 "sex": "1", 82 "age": 18, 83 "favorite": 84 [ 85 { 86 "name":"电影" 87 },{ 88 "name":"旅游" 89 } 90 ] 91 } 92 ]; 93 94 //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 95 //$("#table-template").html()是jquery的语法,不懂的童鞋请恶补。。。 96 var myTemplate = Handlebars.compile($("#table-template").html()); 97 98 //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 99 $('#tableList').html(myTemplate(data)); 100 }); 101 </script> 102 </body> 103 </html>
再融会贯通一下,结合下this,换着姿势玩
<script id="table-template" type="text/x-handlebars-template"> {{#each this}} <tr> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> <td> {{#with favorite}} {{#each this}} <p>{{this}}</p> {{/each}} {{/with}} </td> </tr> {{/each}} </script>
if这个东西啊,到哪都管用
<script id="table-template" type="text/x-handlebars-template"> {{#each student}} {{#if name}} <tr> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> </tr> {{/if}} {{/each}} </script>
也有功力不够的时候,判断条件这种东西还是要在registerHelper里面写
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <META http-equiv=Content-Type content="text/html; charset=utf-8"> 5 <title>由于if功力不足引出的Helper - by 杨元</title> 6 </head> 7 <body> 8 <h1>由于if功力不足引出的Helper</h1> 9 <!--基础html框架--> 10 <table> 11 <thead> 12 <tr> 13 <th>姓名</th> 14 <th>性别</th> 15 <th>年龄</th> 16 </tr> 17 </thead> 18 <tbody id="tableList"> 19 20 </tbody> 21 </table> 22 23 <!--插件引用--> 24 <script type="text/javascript" src="script/jquery.js"></script> 25 <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script> 26 27 <!--Handlebars.js模版--> 28 <!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句--> 29 <!--id可以用来唯一确定一个模版,type是模版固定的写法--> 30 <script id="table-template" type="text/x-handlebars-template"> 31 {{#each student}} 32 {{#if name}} 33 {{#compare age 20}} 34 <tr> 35 <td>{{name}}</td> 36 <td>{{sex}}</td> 37 <td>{{age}}</td> 38 </tr> 39 {{else}} 40 <tr> 41 <td>?</td> 42 <td>?</td> 43 <td>?</td> 44 </tr> 45 {{/compare}} 46 {{/if}} 47 {{/each}} 48 </script> 49 50 <!--进行数据处理、html构造--> 51 <script type="text/javascript"> 52 $(document).ready(function() { 53 //模拟的json对象 54 var data = { 55 "student": [ 56 { 57 "name": "张三", 58 "sex": "0", 59 "age": 23 60 }, 61 { 62 "sex": "0", 63 "age": 22 64 }, 65 { 66 "name": "妞妞", 67 "sex": "1", 68 "age": 18 69 } 70 ] 71 }; 72 73 //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 74 //$("#table-template").html()是jquery的语法,不懂的童鞋请恶补。。。 75 var myTemplate = Handlebars.compile($("#table-template").html()); 76 77 //注册一个比较大小的Helper,判断v1是否大于v2 78 Handlebars.registerHelper("compare",function(v1,v2,options){ 79 if(v1>v2){ 80 //满足添加继续执行 81 return options.fn(this); 82 }else{ 83 //不满足条件执行{{else}}部分 84 return options.inverse(this); 85 } 86 }); 87 88 //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 89 $('#tableList').html(myTemplate(data)); 90 }); 91 </script> 92 </body> 93 </html>
还会碰到一些html编码问题
<!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content="text/html; charset=utf-8"> <title>关于HTML编码 - by 杨元</title> </head> <body> <h1>关于HTML编码</h1> <!--基础html框架--> <table> <thead> <tr> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>个人主页</th> </tr> </thead> <tbody id="tableList"> </tbody> </table> <!--插件引用--> <script type="text/javascript" src="script/jquery.js"></script> <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script> <!--Handlebars.js模版--> <!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句--> <!--id可以用来唯一确定一个模版,type是模版固定的写法--> <script id="table-template" type="text/x-handlebars-template"> {{#each student}} <tr> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> {{#compare age 20}} <td>{{homePage}}</td> {{else}} <td>{{{homePage}}}</td> {{/compare}} </tr> {{/each}} </script> <!--进行数据处理、html构造--> <script type="text/javascript"> $(document).ready(function() { //模拟的json对象 var data = { "student": [ { "name": "张三", "sex": "0", "age": 18, "homePage":"<a href='javascript:void(0);'>张三的个人主页</a>" }, { "name": "李四", "sex": "0", "age": 22, "homePage":"<a href='javascript:void(0);'>李四的个人主页</a>" }, { "name": "妞妞", "sex": "1", "age": 19, "homePage":"<a href='javascript:void(0);'>妞妞的个人主页</a>" } ] }; //注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架 //$("#table-template").html()是jquery的语法,不懂的童鞋请恶补。。。 var myTemplate = Handlebars.compile($("#table-template").html()); //注册一个比较数字大小的Helper,有options参数,块级Helper Handlebars.registerHelper("compare",function(v1,v2,options){ //判断v1是否比v2大 if(v1>v2){ //继续执行 return options.fn(this); }else{ //执行else部分 return options.inverse(this); } }); //将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。 $('#tableList').html(myTemplate(data)); }); </script> </body> </html>
通过{{}}取出来的内容,都会经过编码,也就是说,如果取出的内容中包含html标签,会被转码成纯文本,不会被当成html解析,实际上就是做了类似这样的操作:把<用<替代。
这样做是很好的,既可以显示html代码,又可以避免xss注入。这个功能在做代码展示的时候是非常有用的。
但是有时候我们可能需要解析html,不要转码,很简单,把{{}}换成{{{}}}就可以啦。
本例中,年龄大于20的童鞋个人主页被编码,直接展示出来;而年龄小于20的童鞋,个人主页被当成html解析,显示的是一个超链接。
摘抄完毕,以上代码我都写过自己的测试例子,在花旗快要离职的那段时间每天偷偷看着杨元的博客写的,也非常怀念在花旗上班的日子,虽然学不到什么东西,但是还是给了我一个方向,项目里经常用到handlerbars,所以我才来学,这对我也是一个学习的机会。
感谢所有人!