前言

JsRender是一款基于jQuery的JavaScript模版引擎,它具有如下特点:

·  简单直观

·  功能强大

·  可扩展的

·  快如闪电

这些特性看起来很厉害,但几乎每个模版引擎,都会这么宣传。。。

由于工作需要,小菜才接触到此款模版引擎。使用了一段时间,发现它确实比较强大,但小菜觉得有些地方强大的过头了,反倒让人觉得很难理解。

另一方面,JsRender的官方文档比较详细,但其他资料出奇的少,遇到点什么问题,基本搜不到,不仅仅是相关问题搜不到,几乎就是没有结果。

再加上JsRender有些地方确实是不好理解,所以急需小菜分享一些“最佳实践”。

基于最近一段时间的使用,小菜总结了一些实用经验,当然,这些经验在官方文档上是找不到的。

注意:本文不是基础入门教程,以下例子中自带注释,不做过多说明,读者自行体会,不懂的地方可以留言。

嵌套循环使用#parent访问父级数据(不推荐)

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>嵌套循环使用#parent访问父级数据 --- by 杨元</title>
<style>
</style> </head>
<body> <div>
<table>
<thead>
<tr>
<th width="10%">序号</th>
<th width="10%">姓名</th>
<th width="80%">家庭成员</th>
</tr>
</thead>
<tbody id="list"> </tbody>
</table>
</div> <script src="jquery.min.js"></script>
<script src="jsviews.js"></script> <!-- 定义JsRender模版 -->
<script id="testTmpl" type="text/x-jsrender">
<tr>
<td>{{:#index + 1}}</td>
<td>{{:name}}</td>
<td>
{{for family}}
{{!-- 利用#parent访问父级index --}}
<b>{{:#parent.parent.index + 1}}.{{:#index + 1}}</b>
{{!-- 利用#parent访问父级数据,父级数据保存在data属性中 --}}
{{!-- #data相当于this --}}
{{:#parent.parent.data.name}}的{{:#data}}
{{/for}}
</td>
</tr>
</script> <script>
//数据源
var dataSrouce = [{
name: "张三",
family: [
"爸爸",
"妈妈",
"哥哥"
]
},{
name: "李四",
family: [
"爷爷",
"奶奶",
"叔叔"
]
}]; //渲染数据
var html = $("#testTmpl").render(dataSrouce);
$("#list").append(html); </script> </body>
</html>

嵌套循环使用参数访问父级数据(推荐)

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>嵌套循环使用参数访问父级数据 --- by 杨元</title>
<style>
</style> </head>
<body> <div>
<table>
<thead>
<tr>
<th width="10%">序号</th>
<th width="10%">姓名</th>
<th width="80%">家庭成员</th>
</tr>
</thead>
<tbody id="list"> </tbody>
</table>
</div> <script src="jquery.min.js"></script>
<script src="jsviews.js"></script> <!-- 定义JsRender模版 -->
<script id="testTmpl" type="text/x-jsrender">
<tr>
<td>{{:#index + 1}}</td>
<td>{{:name}}</td>
<td>
{{!-- 使用for循环时,可以在后边添加参数,参数必须以~开头,多个参数用空格分隔 --}}
{{!-- 通过参数,我们缓存了父级的数据,在子循环中通过访问参数,就可以间接访问父级数据 --}}
{{for family ~parentIndex=#index ~parentName=name}}
<b>{{:~parentIndex + 1}}.{{:#index + 1}}</b>
{{!-- #data相当于this --}}
{{:~parentName}}的{{:#data}}
{{/for}}
</td>
</tr>
</script> <script>
//数据源
var dataSrouce = [{
name: "张三",
family: [
"爸爸",
"妈妈",
"哥哥"
]
},{
name: "李四",
family: [
"爷爷",
"奶奶",
"叔叔"
]
}]; //渲染数据
var html = $("#testTmpl").render(dataSrouce);
$("#list").append(html); </script> </body>
</html>

自定义标签(custom tag)中使用else(强烈不推荐)

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自定义标签中使用else --- by 杨元</title>
<style>
</style> </head>
<body> <div>
<table>
<thead>
<tr>
<th width="50%">名称</th>
<th width="50%">单价</th>
</tr>
</thead>
<tbody id="list"> </tbody>
</table>
</div> <script src="jquery.min.js"></script>
<script src="jsviews.js"></script> <!-- 定义JsRender模版 -->
<script id="testTmpl" type="text/x-jsrender">
<tr>
<td>{{:name}}</td>
<td>
{{!-- isShow为自定义标签,price是传入的参数,status是附加属性 --}}
{{isShow price status=0}}
{{:price}}
{{else price status=1}}
--
{{/isShow}}
</td>
</tr>
</script> <script>
//数据源
var dataSrouce = [{
name: "苹果",
price: 108
},{
name: "鸭梨",
price: 370
},{
name: "桃子",
price: 99
},{
name: "菠萝",
price: 371
},{
name: "橘子",
price: 153
}]; //自定义标签
$.views.tags({
"isShow": function(price){
var temp=price+''.split(''); if(this.tagCtx.props.status === 0){
//判断价格是否为水仙花数,如果是,则显示,否则不显示
if(price==(Math.pow(parseInt(temp[0],10),3)+Math.pow(parseInt(temp[1],10),3)+Math.pow(parseInt(temp[2],10),3))){
return this.tagCtxs[0].render();
}else{
return this.tagCtxs[1].render();
}
}else{
return "";
} }
}); //渲染数据
var html = $("#testTmpl").render(dataSrouce);
$("#list").append(html); </script> </body>
</html>

用helper代替自定义标签(推荐)

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用helper代替自定义标签 --- by 杨元</title>
<style>
</style> </head>
<body> <div>
<table>
<thead>
<tr>
<th width="50%">名称</th>
<th width="50%">单价</th>
</tr>
</thead>
<tbody id="list"> </tbody>
</table>
</div> <script src="jquery.min.js"></script>
<script src="jsviews.js"></script> <!-- 定义JsRender模版 -->
<script id="testTmpl" type="text/x-jsrender">
<tr>
<td>{{:name}}</td>
<td>
{{!-- 利用原生的if做分支跳转,利用helper做逻辑处理 --}}
{{if ~isShow(price)}}
{{:price}}
{{else}}
--
{{/if}}
</td>
</tr>
</script> <script>
//数据源
var dataSrouce = [{
name: "苹果",
price: 108
},{
name: "鸭梨",
price: 370
},{
name: "桃子",
price: 99
},{
name: "菠萝",
price: 371
},{
name: "橘子",
price: 153
}]; //Helper
$.views.helpers({
"isShow": function(price){
var temp=price+''.split('');
if(price==(Math.pow(parseInt(temp[0],10),3)+Math.pow(parseInt(temp[1],10),3)+Math.pow(parseInt(temp[2],10),3))){
return true;
}else{
return false;
}
}
}); //渲染数据
var html = $("#testTmpl").render(dataSrouce);
$("#list").append(html); </script> </body>
</html>

代码打包

Download

JsRender实用教程(tag else使用、循环嵌套访问父级数据)的更多相关文章

  1. jsrender-for循环中访问父属性

    jsrender中使用for循环数据时有时需要访问父级数据. 而jsrender在循环中的父级数据存放在隐藏属性parent.parent.data中,使用案例如下 {{:#parent.parent ...

  2. ng-repeat 嵌套访问父作用域里的属性

    在一个项目中,需要嵌套循环输出一个二维表的里的数据 数据结构 [ { id:1, list:[ { id:1, name:'li' } ] }, { id:2, list:[ { id:1, name ...

  3. JsRender实用入门教程

    这篇文章主要介绍了JsRender实用入门实例,包含了tag else使用.循环嵌套访问父级数据等知识点,并提供了完整的实例下载,非常具有实用价值,需要的朋友可以参考下     本文是一篇JsRend ...

  4. freeRTOS中文实用教程3--中断管理之中断嵌套

    1.前言 最新的 FreeRTOS 移植中允许中断嵌套.中断嵌套需要在 FreeRTOSConfig.h 中设置configKERNEL_INTERRUPT_PRIORITY 和configMAX_S ...

  5. js模版引擎handlebars.js实用教程——each嵌套

    <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content="text/ ...

  6. 学习笔记之Java程序设计实用教程

    Java程序设计实用教程 by 朱战立 & 沈伟 学习笔记之JAVA多线程(http://www.cnblogs.com/pegasus923/p/3995855.html) 国庆休假前学习了 ...

  7. js模版引擎handlebars.js实用教程——目录

    写在开头的话: 阅读本文需要了解基本的Handlebars.js概念,本文并不是Handlebars.js基础教程,而是注重于实际应用,为读者阐述使用过程中可能会遇到的一些问题. 实际上,小菜写这篇文 ...

  8. js模版引擎handlebars.js实用教程

    js模版引擎handlebars.js实用教程 阅读本文需要了解基本的Handlebars.js概念,本文并不是Handlebars.js基础教程,而是注重于实际应用,为读者阐述使用过程中可能会遇到的 ...

  9. riot.js教程【六】循环、HTML元素标签

    前文回顾 riot.js教程[五]标签嵌套.命名元素.事件.标签条件 riot.js教程[四]Mixins.HTML内嵌表达式 riot.js教程[三]访问DOM元素.使用jquery.mount输入 ...

随机推荐

  1. ORACLE恢复数据

    ORACLE恢复删除表或表记录 一:表的恢复      对误删的表,只要没有使用PURGE永久删除选项,那么从flash back区恢复回来希望是挺大的.一般步骤有: 1.从flash back里查询 ...

  2. flume远程调试

    项目开发的时候,出现问题的时候,通常在IDE里面直接进行调试,但有时候我们可能用的是另外的一些开源框架,甚至运行程序里面没有一行代码是我们自己写的,如果出现一些较复杂的问题,那么我们可能就会用到远程调 ...

  3. HttpClient请求发送的几种用法:

    /// <summary> /// HttpClient实现Post请求 /// </summary> static async void dooPost() { string ...

  4. [算法]树上倍增求LCA

    LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...

  5. 关于C# 窗体自动隐藏和加载的问题

    最近在写一个小项目,开发一个小程序配合其他软件使用,其中一款软件在使用工作时需要截图生成报告,此时不能有其他应用程式界面在显示器桌面显示,故需要自动隐藏和加载窗体,通过阅读Windows API实现了 ...

  6. 最近在研究备份和虚拟磁带库(LEGATO + MHVTL + SCST + LanFree)

    最近在研究备份和虚拟磁带库(LEGATO + MHVTL + SCST + LanFree) 有些小成功,MHVTL已经搞定,SCST + LANFREE 正在继续实验中,接着就是LEGATO. 最终 ...

  7. MSVC 报错 unable to use inline in declaration get error C2054

    晚上用cmake生成了一份lua-cjson的工程文件,msvc6的 编译时报错 后来再stackoverflow找到答案:unable to use inline in declaration ge ...

  8. 【随笔】ARP和RARP

    ARP协议是什么? ARP协议是"Address Resolution Protocol"(地址解析协议)的缩写.在局域网中,网络中实际传输的是"帧",帧里面是 ...

  9. ubuntu 环境变量修改和恢复总结[收藏]

    在Ubuntu中有如下几个文件可以设置环境变量/etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行./etc ...

  10. 【摘】Chrome解决高版本Stable Beta扩展程序强制停用问题

    博客园插件遇到这个问题,下述摘自百度贴吧,原文地址http://tieba.baidu.com/p/3091171066 1]下载组策略模板 chrome.adm 2] Win+R gpedit.ms ...