前端模板引擎
作者:heero 来源:heero博客 发布时间:2010-07-27 12:33:00
说起模板引擎,很多人会认为这是后台的东西(如PHP的Smarty、Java的Velocity),跟前端没有关系。然而,随着前端的逻辑变得越来越复杂,引入模板技术已经是非常必要了。
模板引擎的主要功能就是把变化的数据融入到不变的模板中,并生成最终结果。目前,前端的主要数据格式无非是XML和JSON。
如果选择XML作为数据格式,XSLT就是最佳的模板语言。大三时做的一个社团网站就是采用了这样的模式。XML+XSLT的缺点非常明显:
兼容性问题。XML+XSLT在不同浏览器下的转换方式有所不同。
XML、XSLT的语法都是极其冗余的,数据量相对较大。
如果选择JSON作为数据格式,似乎没有原生的模板语言可用,只能生拼字符串。例如,把下面代码中的data转换成一个表格:
var data = [
{ id : 1, name : 'Google', url : "google.com" },
{ id : 2, name : '百度', url : "baidu.com" },
{ id : 3, name : '有道', url : "youdao.com" }
], html = [];
html.push('<table>');
for (var i = 0; i < data.length; i++) {
html.push('<tr>');
html.push('<td>', data[i].id, '</td>');
html.push('<td><a href="http://', data[i].url, '" target="_blank">', data[i].name, '</a></td>');
html.push('</tr>');
}
html.push('</table>');
document.write(html.join("\r\n"));
看到这么多单引号、双引号之后,我觉得很头晕。这明显是不可取的。恰巧,大三下学期实习的时候,在一位前辈的代码中看到一种正则表达式做的简单模板引擎:
function parseTemplate(data, tpl) {
return tpl.replace(/\{\$(\w+)\}/g, function($0, $1) {
return data[$1];
});
}
有了parseTemplate后,连接字符串的过程就可以简化为(粗体部分为模板):
html.push('<table>');
for (var i = 0; i < data.length; i++) {
html.push(
parseTemplate(data[i], '<tr><td>{$id}</td><td><a href="{$url}" target="_blank">{$name}</a></td></tr>')
);
}
html.push('</table>');
这样优化过后,代码清晰了一点。然而,这种模板引擎无法应付稍微复杂一点的逻辑。假设我要突出显示排在第一位的数据,parseTemplate就无能为力了。
模板引擎必须要支持for、if等简单逻辑,否则其应用范围就会非常小。然而,要支持这些逻辑,又必须要有一套完善的语法系统。后来,还是著名的Javascript大师John Resig给我们解决了这个问题。他写了一个非常简短的函数实现了支持Javascript语法的模板引擎(详见此处)。其原理是把模板语言“编译”为Javascript的原生语法。这个引擎的优点在于:
可以使用任何Javascript支持的语法。
Parse模板的过程在闭包内执行,不会产生全局变量。
对“编译”后的模板进行了缓存,下次可以跳过“编译”的过程直接使用。
我对这段代码进行了少量改造,添加到jRaiser中,也就是jRaiser.util.parseTpl。主要是把模板语言中的“<%”和“%>”改成了“<#”和“#>”,因为前者容易与后端模板产生冲突。利用这个模板引擎,上面的代码可以再简化为:
var template = '\
<table>\
<# for (var i = 0; i < data.length; i++) { #>\
<tr>\
<td><#=data[i].id#></td>\
<td><a href="<#=data[i].url#>" target="_blank"><#=data[i].name#></a></td>\
</tr>\
<# } #>\
\
</table>';
document.write( $.util.parseTpl(template, { data : data }) );
至此,显示的逻辑已经完全在模板里面,代码清晰明了。
猜你喜欢
- Instr函数与InstrRev函数大家都应该很熟悉,但是如果你看过《ASP * 站开发实践教程》,你应该注意一下。该书中介绍它们时是很有迷
- rem ---表单提示函数 Being-----------------------------CODE Copy ... Fu
- var sss=(String.fromCharCode(127)); var xmlhttp =
- 标志是一种简单的工具,就象铁锤,简单实用。如果一种工具功能太多导致其效用减弱,那就让它保持简单。你并不需要一把有太多装饰的精美铁锤。对于象征
- 当数据库服务器变得十分繁忙导致性能下降时,你会怎么办?购买更多的硬件升级你的服务器,还是重新考虑数据库服务器设计使得数据库平台具备良好的可升
- 在一行内声明CSS,对比下面两个:h2 {font-size:18px; border:1px solid&n
- Hello, 大家好,又是我~ 大家有看过font set和一些要注意的基本问题以及通用字体族两篇文章后,应该对字体的基本有了一些了解。现
- 下面是用SA-FileUp组件上传一个HTML文件的程序:fileup.htm < HTM
- 如何侦测HTTP表头信息?可用下列办法侦测并显示所有的HTTP HEADERS:<HTML><HEAD><TI
- asp如何显示全部的环境变量?<%@Language="VBScript"%><%dim H
- 数据库在时回加for xml auto调用方法 SqlCommand SqlComm=
- 昨天我的电影网站在生成内容静态页面的时候出了问题,提示下标越界,以前从来没有遇到过的,所以根本不知道是什么东西,于是就到处在网上找答案,但是
- Xml_javascript分页实例:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.
- 首先我们知道这个效果应该是一个老话题了。今天整理文件的时候,发现自己以前的一些布局的解决方法躺在文件夹里很长时间了,翻翻老底吧。需要说明的是
- 如何实现让每句话的头一个字母都大写? <%dim txtFnametxtFName = &qu
- LearningjQuery.com 博客帖子列表的左边有一个很酷的日期,如图:从图中我们看到,“2009”垂直排列在右侧。用Firebug
- 1.视图的概述 视图其实就是一条查询sql语句,用于显示一个或多个表或其他视图中的相关数据。视图将一个查询的结果作为一个表来使用,因此视图可
- asp之家注:在网页设计或编程中如何以最方便的方法来处理图片的宽高,以达到最佳的显示效果,这个问题相信很多网页制作人员都遇到过,最麻烦最费时
- 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第四个自然段。以下叙述的脚本包括服务器端脚本和客户端的脚本,服务器端脚本指在服务器上
- 老师罚学生抄写英文单词,结果学生给抄成这样……