Jquery模板(jsrender)
来源:互联网 发布:淘宝鹊桥到期 编辑:程序博客网 时间:2024/06/13 05:18
总之,我是写过无数这样蛋疼的代码:
var html = '';$.each(data.persons, function (i, item) { html += "<tr><td>" + item.FirstName + "</td><td><a href='/Person/Edit/" + item.PersonID + "'>Edit</a> | <a href='/Person/Details/" + item.PersonID + "'>Details</a> | <a href='/Person/Delete/" + item.PersonID + "'>Delete</a></td></tr>";});$('#XXX').append(html);
如果觉得这样还是不明显,可以参见ASP.NET MVC利用PagedList分页(二)PagedList+Ajax+JsRender中的第四部分,这样写很明显的坏处就是:这样的代码可见性太低,很难维护。或许你几个月之后再来看你的代码,你要花半个小时甚至更多才能得出代码的展示结构。下面来看个JsRender的例子:
//Templates<script type="text/x-jsrender" id="personListTemplate"> {{for persons}} <tr> <td>{{:FirstName}}</td> <td> <a href="/Person/Edit/{{:PersonID}}">Edit</a> | <a href="/Person/Details/{{:PersonID}}">Details</a> | <a href="/Person/Delete/{{:PersonID}}">Delete</a> </td> </tr> {{/for}}</script>//Render Datavar html = $("#personListTemplate").render(data);//Insert into Container$("#XXX").append(html);
代码的结构确实清晰可见了,但是代码越看越多了。首先,这是错觉,因为这里的东东都是严格换行了的。其次,这里省去了item、each等字符复杂字符,貌似更容易编写了。
JsRender和Jquery Template
既然JsRender是下一代Jquery模板,那么谁是上一代模板呢?Jquery Template。Jquery Template的特点这里就不废话了,说说JsRedner和Jquery Template的差距:
1、JsRender渲染非常快,网上说的是“和最快一样快”(当然我也不知道他到底有多快)。对于简单的模板的渲染,JsRender的渲染速度比Js Template可以快20倍。
2、JsRender对Dom和Jquery不存在任何依赖(注:不依赖并不是说不使用...)。在Jquery Template 必须用$.template(name,'XXX')标记模板,然后渲染。JsRedner不用,他甚至可以直接渲染字符串。
3、JsRender和Jquery Template相比,JsRender仅仅需要更少的代码,2就是一个例子。
JsRender三要素和行为
从上面贴的代码可以看出,JsRender需要三要素:模板(Template)、容器(Container:简单。。。)、数据(Data:数据可以使各种js对象:如数组,object等等)。主要行为为:渲染模板、将渲染结果插入容器(这个太简单了)。说下渲染模板先。。。
JsRender渲染模板
1、无需编译直接渲染:
var html = $("#XXXXX").render(data); // XXX代表某个脚本标记,也就是上面的<script id="XXX" type="text/x-jsrender">.......</script>
2、渲染前编译:
/*A、获取模板对象的方式编译*/var xxxTemplate = $.templates("#xxxTemplate");//既可以是字符串也可以是脚本标记,B是字符串var html = xxxTemplate.render(data);/*B、指定模板名称的方式编译*/$.templates('xxx','<b>{{:name}}</b>');$.templates({ 'yyy','<b>{{:name}}</b>', 'zzz','<b>{{:name}}</b>'});var html = $.render.xxx(data);//注意,第B种方式可以同时渲染多个模板,但是第A种方式不行
总结一下可以看出:1、无编译直接渲染的方式无法用于字符串的渲染;渲染前编译的方式字符串和脚本标记皆可。2、制定模板名称的方式编译可以同时编译多个模板,但是获取模板对象的方式编译只能编译一个模板。
JsRender模板(Template)
基本的jsRender标签:JsRender模板主要由html标记和jsrender标签(像上面的{{:XXX}})组成。所有的Jsrender标签都被两个大括号包裹,中间既可以是参数也可以使表达式(如:{{:#index}}和{{:#index+1}}),下面看一下一些基本的Jsrender标签。
描述例子输出参数firstName的值(未被Html编码){{:firstName}}Madelyn参数movie的属性--releaseYear的值(未被html编码){{:movie.releaseYear}}1987比较(表达式,未被html编码){{:movie.releaseYear < 2000}}true经html编码的值(更加安全,但是要耗点内存){{>movie.name}}Star Wars: Episode VI: <span style='color:purple;font-style: italic;'>Return of the Jedi</span>经html编码的值{{html:movie.name}}Star Wars: Episode VI: <span style='color:purple;font-style: italic;'>Return of the Jedi</span>
jsrender数据遍历:看过ASP.NET MVC利用PagedList分页(二)PagedList+Ajax+JsRender的童鞋对jsrender的数据遍历相信不会陌生,基本语法如下:
{{for xxx}} <li>{{:property of xxx}}</li>{{/for}}
有时候想获取xxx本身怎么办呢?如下:
{{for xxx yyy}} <li>{{:#data}}</li>{{/for}}
上面的例子要说明两点:1、for不仅仅可以遍历一组数据,他甚至可以同时遍历两组和多组数据(强大了吧...)。2、上面的#data就表示xxx和yyy本生。试想一下,如何xxx和yyy都表示一个基本元素(字符串、整数等等、任意交叉)的数组,那么这个是不是能很好的完成遍历呢?说道#data,不得不提一下#index,#data和#index都是内置的jsrender关键字。下面在一个例子:
//Template{{for #data}} <h3>{{:name}}</h3> <ul> {{for language}} <li> {{:#parent.parent.data.name}} is learning {{:title}}</li> {{/for}} </ul>{{/for}}//Data var studnets = [ { "name": "Mingjun Tang", "language": [{ "title": "English"},{ "title": "Franch"}] }, { "name": "Ming Tang", "language": [{ "title": "English"}] }];
遍历时#data充当了students,同时#parent.parent.data.XXX可以用于向上迭代。注意这里的data并不是student中的属性额,因为#parent向上迭代后返回的是一个jsrender对象只有,#parent.data后才会返回数组内容。#parent在jsrender叫路径访问,但是我觉得这里叫向上迭代还要好些。
jsrender条件:
{{if fullprice}} html markup{{else halfprice}} html markup{{else}} html markup{{/if}}
也可以吧他们扯开用,如:{{if fullprice}}html markup{{/if}}和{{if fullprice}}html markup{{else}}html markup{{/if}}。但是这里需要注意两点:
1、if....else....else表示了if elseif else,这里的else表示了elseif。
2、{{if fullprice}}中的fullprice条件表达式表示的是fullprice不为空。其实还可以有更懂的条件表达式可以应用到这里来,如下(注意这里的等于和不等于、、、、):
表达式举例注释||{{ :a || b }}或&&{{ :a && b }}且!{{ :!a }}非<= 和>=和 <和 >{{ :a <= b }}比较=== 和 !=={{ :a === b }}等于和不等于3、在条件表达式中还可以用一些属性进行比较,如{{if xxx.length > 50}}等等
jsrender模板嵌套:
在上面一个例子中,嵌套了两个for循环,试想一下,如果这两个for循环结构非常复杂或其下还要嵌套一个甚至多个for循环的时候,上面所说的jsrender提高了代码的可见性和可维护性就不复存在了。于是jsrender也提供了jsrender模板的嵌套,改写一下上上面的JsRender模板:
<script type="text/x-jsrender" id="studentTemplate"> {{for #data}} <h3>{{:name}}</h3> <ul> {{for language tmpl="#studentLanguageTemplate" /}} </ul> {{/for}}</script><script type="text/x-jsrender" id="studentLanguageTemplate"> <li> {{:#parent.parent.data.name}} is learning {{:title}}</li></script>//render$("#studentList").html($("#studentTemplate").render(studnets));
这样就可以避免无限的嵌套下去,只需要设置{{for}}的tmpl属性即可。这时,tmpl是一个脚本标记。如果studentLanguageTemplate已经被$.templates()编译,那么也可以这么写:
<script type="text/x-jsrender" id="studentTemplate"> {{for #data}} <h3>{{:name}}</h3> <ul> {{for language tmpl="studentLanguageTemplate" /}} </ul> {{/for}}</script><script type="text/x-jsrender" id="studentLanguageTemplate"> <li> {{:#parent.parent.data.name}} is learning {{:title}}</li></script>//render$.templates("studentLanguageTemplate", "#studentLanguageTemplate");$("#studentList").html($("#studentTemplate").render(studnets));
上面的templ不再“#XXX”指向一个脚本标记,而是"XXX"指向一个已经标记的脚本标记。(哈哈 说起来还真绕口)。
OK,基础的东东就差不多了。不过除了着了,Jsrender还具备良好的可扩展性。后头在慢慢来看看。。。。。
Demo下载: https://github.com/BorisMoore/jsrender/zipball/master
- Jquery模板(jsrender)
- 用MVC做可拖拽的留言板,利用 Jquery模板 -- JsRender
- JSRender之渲染模板
- JSRender之渲染模板
- JSRender之渲染模板
- JsRender
- JavaScript中的模板(jsRender)在Django中的使用
- JsRender 点滴
- JSrender渲染
- jQuery模板
- JQuery模板
- Jquery模板
- jsrender简单例子
- jsrender 学习 入门 demo
- jsRender的使用
- jsrender 绑定数据
- jsrender的使用总结
- jsrender页面数据的展示
- (19)获取根目录
- 给傻瓜用的SP2010开发--第一部分--理解SP开发平台--第一章节--理解SP促销讨论(3)--所以,到底什么是SP呢
- 黑马程序员--java基础--抽象类
- JQuery中extend怎么用
- Eclipse异常集锦
- Jquery模板(jsrender)
- Makefile:xxx: recipe for target xxx failed +【顺带搞懂了】如何忽略makefile执行过程中的某些命令的错误而得以继续运行
- 音乐播放器1
- 程序员该如何逃离困境
- Configure SMTP插件解决WordPress邮件发送问题
- MyEclipse10在function定义document.onkeydown出错
- RageSpline 2d卡通插件的基本操作
- UVa 11008 Antimatter Ray Clearcutting / 状态压缩DP
- erlang变量赋值出错exception error: no match of right hand side value