H5 中都是 Html,在这里我们没有 el 标签。所以我们只能借助模板。好处上面已经介绍了
<!– more –>
扫码关注公众号,不定期更新干活
web 开发中,js 解析 JSON 是经常的事情。非常繁琐。handlebars 使用了模版,只要你定义一个模版,提供一个 json 对象,handlebars 就能吧 json 对象放到你定的模版中,非常方便好用!
- H5 中都是 Html,在这里我们没有 el 标签。所以我们只能借助模板。好处上面已经介绍了。
H5 中循环遍历
- 第一步:在 html 中定义模板,将后台的 json 放在模板里。
<script id="task-table-template" type="text/x-handlebars-template">
{{#each this}}// 遍历循环的格式,相当于 foreach
<a href="{{link}}">//json 中的 link 必须是 {{}} 格式
<strong>
{{Obj_title}}// 同上
</strong>
</a>
{{/each}}
</script>
- 第二步:在 js 中实例化这个模板
var myTemplate = Handlebars.compile($("#task-table-template").html());
- 第三步:将后台 json 传进来显示,并确定模板显示位置,下面的列子 将模板显示在 class=notice_srcoll 的 div 上
$('.notice_srcoll').html(myTemplate(data.noticeTasklist));
- 这里提到的 json 就是我们熟悉的 json, 给一个列子看看
var data = { users: [{username: "alan", firstName: "Alan", lastName: "Johnson", email: "alan@test.com"},
{username: "allison", firstName: "Allison", lastName: "House", email: "allison@test.com"},
{username: "ryan", firstName: "Ryan", lastName: "Carson", email: "ryan@test.com"}
]};
H5 中 if else 的使用
- handlebar 中 if else 只支持原生态的,也就是只支持 true 和 false 的判断,但是事实上我们的逻辑中很多情况下的判断并不是仅仅就 true 和 false,这个时候我们这么办呢。先看看原生态的 if else
{{#if score}}
<li>
<font>
<input type="checkbox" name="you" id="{{id}}" class="regular-checkbox big-checkbox" value="{{id}}" checked disabled/>
<label for="{{id}}"></label>
</font>
<div class="li_div">
<strong>
{{name}}
</strong>
<p> 主讲老师
{{teacher}}
</p>
</div>
</li>
{{else}}
<li>
<font><input type="checkbox" name="you" id="{{id}}1" class="regular-checkbox big-checkbox" value="{{id}}" />
<label for="{{id}}1"> </label>
</font>
<div class='li_div'>
<strong>
"{{name}}"
</strong>
<p> 主讲老师
{{teacher}}
</p>
</div>
</li>
{{/if}}
- 这里的判断就是说 score 未 undefined null false [] 返回的都是 false,在这里并不能判断分数大小。这个时候我们通过 Handlebars.registerHelper 用来定义 Helper 来对 handlebars 就醒扩展。
- html 代码
{{#compare age 20}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{else}}
<tr>
<td>?</td>
<td>?</td>
<td>?</td>
</tr>
{{/compare}}
- js 对 handlebars 扩展
// 注册一个比较大小的 Helper, 判断 v1 是否大于 v2
Handlebars.registerHelper("compare",function(v1,v2,options){if(v1>v2){
// 满足添加继续执行
return options.fn(this);
}else{// 不满足条件执行 {{else}} 部分
return options.inverse(this);
}
});
- 这里需要说明一下,在利用 Handlebars.registerHelper 注册事件时,如果后面的 function 中没有传 options 的话我们就可以直接调用,如果有 options 的话,我们需要在前面加上 #, 因为加上 options 的话是块级别的 Helper。
- 事列一
Handlebars.registerHelper("addOne",function(index,options){return parseInt(index)+1;
});
- 调用
<label for="checkbox-2-{{addOne @index}}"></label>
- 事列二
Handlebars.registerHelper("compare",function(v1,v2,options){if(v1>v2){
// 满足添加继续执行
return options.fn(this);
}else{// 不满足条件执行 {{else}} 部分
return options.inverse(this);
}
});
- 调用
{{#compare age 20}}
- 原声 if 还支持多级判断
{{#if name.xxx}},这样写就假设 name 属性是一个 map,检测 name 属性中是否包含 xxx 属性。
Helper 中 options 参数
- 这里参考网上一篇博客的案列
{{#sort ages id="ages-list" class="con"}}
<span>{{@name}}:{{this}}</span>
{{/sort}}
- 经过编译后上面这段信息被分装在 options 里了。下面是注册代码
// 上面的信息在下面的 options 里
Handlebars.registerHelper("sort",function(context,options){
var i = 0,str="<div id="+ options.hash.id +"class="+ options.hash.class +">";
for(;i<context.length;i++){str+=options.fn(context[i],{data:{name:options.data[i]}});
}
str+="</div>";
return str;
});
-
helper 中的 options 包含了那些信息?
- data:可以在渲染模板时,将其传进去,如 template(context, {data: data})。(// 这里后面会涉及)
- hash : 保存写模板时,可以将一些值以 key-value 对的形式传进去, 比如上面的 div 里有 ID 和 classs 属性,这两个都是键值对,都会存在 options.hash 中,这里我们可以看成是 map
- fn:方法,官方解释说“options.fn 的可以被认为是被编译过的普通 handlebars 模板,它的调用的执行环境被认为是‘this’,所以你可以把 this 作为执行上下文去调用它”,这里存放了上面那个 div 中的闭环体。什么是闭环体?所谓闭环体就是有开有闭,上面 div 里那个 span 就是闭环体,<zzz></zzz> 形如这样的就是闭环体。
- inverse : 给 if 的 block 的 else 来用的. 说白了就是给 {{else}} 使用的。
- 数据源及模板渲染
var template = Handlebars.compile($("#people-template").html());
var temp = {ages:[23,24,56,64]}
var result = template(temp,{data:["tom","jak","lili","jim"]});
/*result:
<div id="ages-list" class="con">
<span>jak:24</span>
<span>lili:56</span>
<span>jim:64</span>
</div>
- 模板渲染中用到
var result = template(temp,{data:["tom","jak","lili","jim"]});
就是在渲染时传入 data 数据. 正常情况下传递一个 json 数据,当传两个 json 了,第二个 json 里的数据就是替换模板中的占位符的 ({{@…}} 这种写法的占位符). - str+=options.fn(context[i],{data:{name:options.data[i]}}); 这句话就是将模板渲染时传入的数据中的 name 字段付给 {{@name}} 这个占位符。context[i]就是传给文中 {{this}} 也就是相当于 {{ages}} 的。在渲染时一定要匹配,比如我的数据源是 ages 那就一定要用 ages, 那为什么我上面用的是{{this}}, 因为我在 div 中的 ages, 所以 div 下面的上下文 this 指代的就是 ages.
仿 each 写高级 list
- 模板
{{#each comments}}
<div class="comment">
<h2>{{subject}}</h2>
{{{body}}}
</div>
{{/each}}
- 在上面的模板中看出,我们遍历出的是 div,div 本身就是闭环体,都在我们的 options.fn 中,所以我们的 helper 就直接遍历就行了。
Handlebars.registerHelper('each', function(context, options) {
var ret = "";
for(var i=0, j=context.length; i<j; i++) {ret = ret + options.fn(context[i]);
}
return ret;
});
- 根据这个我们完全可以写出更加高级的遍历
- 模板
{{#list nav}}
<a href="{{url}}">{{title}}</a>
{{/list}}
- helper 不难看出 a 是闭环体,也就是我们传入值,options.fn 中就自动有
<a></a>
, 我们需要做的是加上<ul></ul>
, 并在每一项上加上<li></li>
闭环体。这样就显的更加有规格了。这也是官网上提供的。
Handlebars.registerHelper('list', function(context, options) {
var ret = "<ul>";
for(var i=0, j=context.length; i<j; i++) {ret = ret + "<li>" + options.fn(context[i]) + "</li>";
}
return ret + "</ul>";
});
H5 空白处理
- 模板中的空白可以忽略,mustache 声明的两边都可以,只需添加一个 ~ 字符即可。写了这个之后,这一边的所有空白都会被移除,直到最近的 Handlebars 表达式或这一边的非空白字符
{{#each nav ~}}
<a href="{{url}}">
{{~#if test}}
{{~title}}
{{~^~}}
Empty
{{~/if~}}
</a>
{{~/each}}
{
nav: [{url: 'foo', test: true, title: 'bar'},
{url: 'bar'}
]
}
- 得出的结果没有换行,也没有格式化用的空白符:
<a href="foo">bar</a><a href="bar">Empty</a>
部分资料参考!!!
扫码关注公众号,不定期更新干活
加入战队
<span id=”addMe”> 加入战队 </span>
微信公众号