Jtemplete/客户端模板的脚本渲染引擎

本文介绍了如何使用jsTemplate进行客户端模板渲染,通过DWR的回调函数展示数据。讲解了如何导入template.js,创建隐藏的textarea存放模板,并在JavaScript中使用TrimPath.processDOMTemplate()方法将数据与模板结合。此外,还详细解析了jsTemplate的API,包括capitalize、default、eat和escape等属性的用法,以及if、for等控制流和循环的语法。文章通过一个综合实例展示了jsTemplate的使用,包括模板定义、数据处理和JavaScript代码的minify等操作。
摘要由CSDN通过智能技术生成

jsTemplate最新的版本是1.038不过这已经是2005年7月8日发布的了
还是上面DWR的那个AnnotationSpring例子不过我们把javafish的信息放到表格里.
先在官方下载template.js文件,然后在AnSpringUserInfoHtml.html里导入这个js文件:<script type='text/javascript' src='template.js'></script>
然后在AnSpringUserInfoHtml.html里加入一个隐藏的textare:

Java代码
  1. <textarea id="person" style="display:none;">  
  2.         <table>  
  3.             <tr>  
  4.                 <td>姓名:</td>  
  5.                 <td>${username}</td>  
  6.             </tr>  
  7.             <tr>  
  8.                 <td>年龄:</td>  
  9.                 <td>${age}</td>  
  10.             </tr>  
  11.             <tr>  
  12.                 <td>住址:</td>  
  13.                 <td>${address}</td>  
  14.             </tr>  
  15.             <tr>  
  16.                 <td>我们欢迎:</td>  
  17.                 <td>${welcome}</td>  
  18.             </tr>  
  19.         </table>  
  20.     </textarea>  
<textarea id="person" style="display:none;">
  <table>
   <tr>
    <td>姓名:</td>
    <td>${username}</td>
   </tr>
   <tr>
    <td>年龄:</td>
    <td>${age}</td>
   </tr>
   <tr>
    <td>住址:</td>
    <td>${address}</td>
   </tr>
   <tr>
    <td>我们欢迎:</td>
    <td>${welcome}</td>
   </tr>
  </table>
 </textarea>


最后在自己发挥的那个anspringuserInfo.js把DWR的回调函数写成:
var user = msg;
DWRUtil.setValue('result',TrimPath.processDOMTemplate("person", user));
大功告成运行一下服务器看看吧.javafish的信息就以表格的形式给出来了
这也算是个HelloWorld例子了吧,不过这也已经把jsTemplate用的差不多了,jsTemplate非常的简单,不过有些地方需要一些技巧,…等到后面再说吧.
先解释一下上面的用法:
Template.js是解悉模板的函数库。

渲染的模板,官方推荐是写在一个隐藏的textare里(用别的也可以不过在有时候会发生一些问题,

还是推荐用textare)比如:<textare id=”..” style=”display:none”>在这里添加jsTemplate模板</textare>。

而模板呢,一般静态的来说就是 HTML代码不过变量就用类似于表达式语言(其实很像freemaker).在上面例子中的模板里大家都想知道的就是类似${username}的东西吧,大家看一下回调函数传回来的对象是什么,就是User类的getUser方法,返回的是User对象,而现在用${}引用的正是这个对象里的成员,而它们之间是怎么联系起来的呢?一开始回调函数回传的msg就是User类的getUser的返回值user对象,然后把msg传给新定义的user再用

 TrimPath.processDOMTemplate("person", user) 就把回传的user对象和id为person的textare联系到一起了.


下面分别研究一下jsTemplate的API,语法:
其实我们就用到一个API-TrimPath.processDOMTemplate(),其它都是自己内部用(可以具一下官方的template.js文件的代码).这个函数的返回的就是一个innerHTML,而对于${}里面的变量有几个属性:
1. capitalize大写,可以在上面的例子中的username作文章:${username|capitalize}运行一下会发现原来的javafish成了JAVAFISH了
2. default:”值” 当${}里的变量为null的时候以默认设置的代替,还是上面那个例子:不过加上点东西

Java代码
  1. <tr>  
  2.                 <td>性别</td>  
  3.                 <td>${sex|default:"男"}</td>  
  4. </tr>  
<tr>
    <td>性别</td>
    <td>${sex|default:"男"}</td>
   </tr>


Java代码
  1. <td>${welcome|default:"客人"}</td>  
<td>${welcome|default:"客人"}</td>


可是结果呢,并不如人意在性别上显示:性别 [ERROR: ReferenceError: sex is not defined; sex is not defined]
在欢迎词上一点东西也不显示!
这是因为default只是显示为null的,而上面的第一个sex无论是在服务器端,还是客户端的对象里都是没有定义的,所以会出现异常.
第二个的welcome虽然已经被定义了,但是它不是null它是””.,不过这些我们可以在服务端把welcome设为null,现在看一下服务端的代码,发现对象中有一个是null的就是books,现在把上面性别的代码的sex改成books试试,呵呵成功了
3. eat 吃掉,这个属性很有用,当我们想用${}访问运行对象里的函数但又不想有内容输出的时候就用这个属性.
4、escape 转换HTML代码使之可以输出,
还是上面的例子,运行一下,在请输入自己的名字后面的文本框里输入<font color='red'>likunkun</font>点击得到javafish的信息,看到欢迎词不是 欢迎<font color='red'>likunkun</font>而是:欢迎likunkun,likunkun的颜色变成了红色的了,这也不是我们想要的,怎么才能让结果出现欢迎<font color='red'>likunkun</font>呢?这就用到escape属性了,把${welcome}改成$ {welcome|escape}运行一下就出现我们想要的结果了:我们欢迎: <font color='red'>likunkun</font>
下面看一下jsTemplate模板的语法:
1. 定义数据,jsTemplate模板的定义数据的方法和javascript中是一样的(用var)
2. 控制流,官方给的不错:

Java代码
  1. {if testExpr}   
  2.     {elseif testExpr}  
  3.     {else}  
  4.   {/if}  
{if testExpr} 
    {elseif testExpr}
    {else}
  {/if}


这些语句是可以嵌套的(和vb里面的IF有点像),一会面有个综合的例子的.

在jsTemplate里有一个配合if的函数defined()[defined是来判断传入的对象是否已被定义]
3. 循环,官方给的也很好:

Java代码
  1. {for varName in listExpr}  
  2.   {/for}  
  3.   
  4.   {for varName in listExpr}  
  5.     ...main body of the loop...  
  6.   {forelse}  
{for varName in listExpr}
  {/for}

  {for varName in listExpr}
    ...main body of the loop...
  {forelse}


当迭代的List为null或它的长度为0的时候输出的
{/for}
可以看一个例子来体会这个循环的用法:
var book = {java[{title:javaWeb 开发详解,author:孙鑫},{title:vc++深入详解,author:孙鑫}]};
我们就可以用
{for bk in java}
bk.title,bk.author
{forelse}
没有书
{/for}
可能大家有些问题是:如果一个纯Array数组怎么办呢{for}里面的bk in 什么呢?
我在javaeye发了一个讨论帖http://www.javaeye.com/topic/40368,可以看一下.
自己想了个变通的小技巧就是:
如果var book = [{title:"java web开发详解", author:"孙鑫"},{title:"vc++深入详解", author:"孙鑫"}];
我们在javascript里加入

Java代码
  1. var jsbook = {};    
  2. jsbook.sbook=book;   
var jsbook = {};  
jsbook.sbook=book; 


然后这样

Java代码
  1. {for bks in sbook}    
  2.      <tr><td>${bks.title}</td><td>${bks.author}</td>    
  3.          </tr>    
  4.  {forelse}    
  5.      <tr><td colspan="2">没有书</tr>    
  6. {/for}  
{for bks in sbook}  
     <tr><td>${bks.title}</td><td>${bks.author}</td>  
         </tr>  
 {forelse}  
     <tr><td colspan="2">没有书</tr>  
{/for}


就ok了嘻嘻
4. {CDATA}这里的代码将被jsTemplate忽略{/CDATA}
5. 在jsTemplate模板里加入javascript的时候用{eval}{/eval}
6. 有的时候可能会在html代码里面放入javascript比如<input type=”button” οnclick=”alert(‘你好!’);”/>不过代码可能不会是一句alert()这么简单,可能会很多行,这就需要用{minify} {/minify}来包围这些行,而{minify}不但可以用于javascript中还可以把CSS用于html的style中.
最后看一个综合的例子,:
还是上面DWR的例子UserInfo.html吧
现在我把它改的一塌糊涂了:

Java代码
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  2. <html>  
  3.   <head>  
  4.     <title>UserInfo.html</title>  
  5.     <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
  6.     <script type='text/javascript' src='template.js'></script>  
  7.     <script type='text/javascript' src='dwr/interface/jsuser.js'></script>  
  8.     <script type='text/javascript' src='dwr/engine.js'></script>  
  9.     <script type='text/javascript' src='dwr/util.js'></script>  
  10.     <script type="text/javascript" src="userInfo.js"></script>  
  11.   
  12.   </head>  
  13.     
  14.   <body>  
  15.     请输入你的名字:  
  16.     <input id="name" type="text"/>  
  17.     <input id="jbutton" type="button" value="得到javafish的信息"/>  
  18.     <input id="sbutton" type="button" value="得到javafish的书"/>  
  19.     <div id="result"></div>  
  20.     <script>load()</script>  
  21.     <textarea id="books" style="display:none">  
  22.         <table style="{minify}  
  23.             background-color:red;  
  24.             font-size:small;  
  25.             color:green;  
  26.         {/minify}">  
  27.             <tr><td>书名</td><td>作者</td></tr>  
  28.         {for bks in javabook}  
  29.             <tr><td>${bks.name}</td><td>${bks.author}</td></tr>  
  30.         {forelse}  
  31.             <tr><td colspan=2>当前没有书</td></tr>  
  32.         {/for}  
  33.             <tr><td>{cdata}${bks.name}它本来应该输出书名可是现在被jsTemplate忽略了{/cdata}</td></tr>  
  34.             <input type='button' value='确定' οnclick='{minify}  
  35.                 alert("多行中的第一行");  
  36.                 alert("多行中的第二行");  
  37.             {/minify}'/>  
  38.             <input id="li" type='button' value="eval测试" οnclick="evalonclick()"/>  
  39.             {eval}  
  40.             evalοnclick=function()  
  41.             {  
  42.                 alert("测试一下eval");  
  43.             }  
  44.             {/eval}  
  45.         </table>  
  46.     </textarea>  
  47.     <textarea id="person" style="display:none;">  
  48.         <table>  
  49.             <tr>  
  50.                 <td>姓名:</td>  
  51.                 <td>${username|capitalize}</td>  
  52.             </tr>  
  53.             <tr>  
  54.                 <td>年龄:</td>  
  55.                 <td>${age}</td>  
  56.             </tr>  
  57.             <tr>  
  58.                 <td>用sex表示的性别</td>  
  59.                 <td>{if defined("sex")}  
  60.                     ${sex|default:"男"}  
  61.                     {else}  
  62.                     用sex表示的性别没有定义  
  63.                     {/if}</td>  
  64.             </tr>  
  65.             <tr>  
  66.                 <td>住址:</td>  
  67.                 <td>${address}</td>  
  68.             </tr>  
  69.             <tr>  
  70.                 <td>我们欢迎:</td>  
  71.                 <td>${welcome|escape}</td>  
  72.             </tr>  
  73.         </table>  
  74.     </textarea>  
  75.   </body>  
  76. </html>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>UserInfo.html</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 <script type='text/javascript' src='template.js'></script>
    <script type='text/javascript' src='dwr/interface/jsuser.js'></script>
 <script type='text/javascript' src='dwr/engine.js'></script>
 <script type='text/javascript' src='dwr/util.js'></script>
    <script type="text/javascript" src="userInfo.js"></script>

  </head>
  
  <body>
   请输入你的名字:
   <input id="name" type="text"/>
    <input id="jbutton" type="button" value="得到javafish的信息"/>
 <input id="sbutton" type="button" value="得到javafish的书"/>
 <div id="result"></div>
 <script>load()</script>
 <textarea id="books" style="display:none">
  <table style="{minify}
   background-color:red;
   font-size:small;
   color:green;
  {/minify}">
   <tr><td>书名</td><td>作者</td></tr>
  {for bks in javabook}
   <tr><td>${bks.name}</td><td>${bks.author}</td></tr>
  {forelse}
   <tr><td colspan=2>当前没有书</td></tr>
  {/for}
   <tr><td>{cdata}${bks.name}它本来应该输出书名可是现在被jsTemplate忽略了{/cdata}</td></tr>
   <input type='button' value='确定' οnclick='{minify}
    alert("多行中的第一行");
    alert("多行中的第二行");
   {/minify}'/>
   <input id="li" type='button' value="eval测试" οnclick="evalonclick()"/>
   {eval}
   evalοnclick=function()
   {
    alert("测试一下eval");
   }
   {/eval}
  </table>
 </textarea>
 <textarea id="person" style="display:none;">
  <table>
   <tr>
    <td>姓名:</td>
    <td>${username|capitalize}</td>
   </tr>
   <tr>
    <td>年龄:</td>
    <td>${age}</td>
   </tr>
   <tr>
    <td>用sex表示的性别</td>
    <td>{if defined("sex")}
     ${sex|default:"男"}
     {else}
     用sex表示的性别没有定义
     {/if}</td>
   </tr>
   <tr>
    <td>住址:</td>
    <td>${address}</td>
   </tr>
   <tr>
    <td>我们欢迎:</td>
    <td>${welcome|escape}</td>
   </tr>
  </table>
 </textarea>
  </body>
</html>


然后把UserInfo.js的回调函数改为

Java代码
  1. function callbackBooks(msg)  
  2. {  
  3.     var book = msg;  
  4.     book.javabook=msg;  
  5.     DWRUtil.setValue('result',TrimPath.processDOMTemplate("books", book));  
  6. }  
  7. function callback(msg)  
  8. {  
  9.     var user = msg;  
  10.     DWRUtil.setValue('result',TrimPath.processDOMTemplate("person", user));  
  11. }  
function callbackBooks(msg)
{
 var book = msg;
 book.javabook=msg;
 DWRUtil.setValue('result',TrimPath.processDOMTemplate("books", book));
}
function callback(msg)
{
 var user = msg;
 DWRUtil.setValue('result',TrimPath.processDOMTemplate("person", user));
}


这样的话上面的例子基本上把jsTemplate的的内容含盖了.

 

 

客户端打印可以利用这个技术,先把打印模板建立好,然后渲染为InnerHtml.然后把它写到隐藏内置框架。

然后调用window.print方法打印内置框架内容就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值