为什么要使用模板引擎

DOM结构简单,完全可以使用DOM方法创建DOM树。$("<td></td").appendTo();

当页面比较复杂的时候,下面的程序中红色部分来自JSON中的数据:

<div class="feeds-item hasImg" id="item-702635">

<p class="feeds-item-pic">

<a href="http://gupowang.baijia.baidu.com/article/702635" target="_blank" >

<img src="http://d.hiphotos.baidu.com/news/crop%3D0%2C1%2C612%2C367%3Bw%3D638/sign=243504ed134c510fba8bb85a5d69091c/e1fe9925bc315c6097d9b1ca84b1cb1349547743.jpg"></a>

</p>

<h3>

<a href="http://gupowang.baijia.baidu.com/article/702635" target="_blank" mon="col=13&amp;pn=2">Snap这款眼镜真能带来一场社交革命吗?</a>

</h3>

<p class="feeds-item-text1">

Snapchat母公司Snap在11月10日推出的一款智能眼镜——Spectacles,目前在美国亚马逊网站里的合作商户页面标价依然高达1599美元,...

</p>

<div class="feeds-item-info">

<p class="labels">

<span class="label">

<a class="labelnm" href="http://baijia.baidu.com/?tn=listarticle&amp;labelid=142650" target="_blank">snap</a>

</span>

<span class="label">

<a class="labelnm" href="http://baijia.baidu.com/?tn=listarticle&amp;labelid=24262" target="_blank">眼镜</a>

</span>

<span class="label">

<a class="labelnm" href="http://baijia.baidu.com/?tn=listarticle&amp;labelid=26751" target="_blank">社交革命</a>

</span>

</p>

<a href="http://gupowang.baijia.baidu.com/" class="feeds-item-author" target="_blank">姑婆那些事儿</a> <i class="public-v"></i>

<span class="tm">10:14</span>

<span class="count">阅读(9)</span>

<a href="javascript:;" class="share-article"> <i class="i ishare"></i>

分享

<dl class="changeshare">

<dd class="sina"></dd>

<dd class="qzone"></dd>

<dd class="wechat"></dd>

</dl>

</a>

</div>

</div>

如果使用DOM方法创建上面的结构,太复杂了!不容易进行更改。此时最好的办法就是“模板引擎”。

模板引擎的原理

就是字符串的replace函数。

最简单的replace函数:

<script type="text/javascript">
var str = "我爱杨洋,杨洋很帅,杨洋很会唱歌";
str = str.replace(/杨洋/g,"李易峰");
alert(str);
</script>

replace函数的第二个参数可以是函数:

    <script type="text/javascript">
var str = "我爱杨洋,杨洋很帅,杨洋很会唱歌";
str = str.replace(/杨洋/g,function(){
return "李易峰";
});
alert(str);
</script>

分组捕获,可以使用$1来参与生成替换字符串,比如把人民币换成美元。

    <script type="text/javascript">
var str = "我一共有100元,早饭10元,午饭20元,晚饭15元。";
str = str.replace(/([\d]+)元/g,function(match,$1){
return $1 / 6.2 + "美元";
});
alert(str);
</script>

模板原理:

    <script type="text/javascript">
//模板字符串
var str = "好{{xinqing}}啊,今天我买了{{dongxi}},花了{{qian}}元";
//字典(数据)
var dictionary = {
"xinqing" : "高兴",
"dongxi" : "手机",
"qian" : 1000
}
//数据绑定
str = str.replace(/{{(\w+)}}/g,function(match,$1){
return dictionary[$1];
});
//显示结果
alert(str);
</script>

模板一共要三步走:

① 准备模板字符串。所谓的模板字符串就是含有模板标记的字符串,模板标记可以任意设置。

② 准备字典(这个名字是前几年流行的,现在就单纯的叫做“数据”)

③ 数据绑定,其实很简单就是用字典的v去对用替换模板标记k的那个地方。

一般不使用自己开发的模板引擎解析程序,因为不好用,比如模板标记加上空格,就不能识别了。

一般使用underscore来进行模板操作。

    <script type="text/javascript" src="js/underscore-min.js"></script>
<script type="text/javascript">
//模板字符串
var str = "好<%=xinqing%>啊,今天我买了<%=dongxi%>,花了<%=qian%>元"; //准备编译函数,使用underscore提供的template函数,接受一个模板字符串,返回一个函数。
var compiled = _.template(str);
//数据绑定
var str2 = compiled({
"xinqing" : "高兴",
"dongxi" : "手机",
"qian" : 1000
}); alert(str2);
</script>

使用underscore进行模板操作的时候:

① 准备模板字符串,模板标记不能任意执行,必须是<%=%>。其实underscore源码中可以自由更改。

② 生成一个编译函数,使用内置的_.template()函数,template就是模板的意思。这个函数接受一个字符串(就是刚才的模板字符串)当做参数,返回一个函数。

③ 数据绑定,直接调用刚才生成的compiled函数,把字典往里面扔,此时就能返回绑定之后的字符串。

模板引擎的使用

首先我们准备一个复杂JSON:

后台哥哥生成了JSON,他的工作就完成了,不管前端是如何进行数据可视化的。

然后进行界面的HTML、CSS开发,把重复的部分,放到

<script type="text/template"></script>

不一定一定是text/template,只要不是test/javascript就行了。浏览器认为遇见了一个陌生的语言,从而静默,不予处理,不报错。

把需要使用模板的地方,使用模板标记替换。注意,模板标记中的英语单词,必须要根据字典中的key来决定。

<script type="text/template" id="feeds_template">
<div class="feeds">
<div class="pic">
<a href="<%= m_display_url %>">
<img src="<%= m_image_url %>" alt="" />
</a>
</div>
<div class="feed_main">
<h3>
<a href="<%= m_display_url %>">
<%= m_title %>
</a>
</h3>
<p class="summary">
<%= m_summary %>
</p>
<div class="info">
<span class="writer"><%= m_writer_name %></span>
<span><img src="data:images/v.png" alt="" /></span>
<span class="time"><%= m_create_time %></span>
<span class="yuedu">阅读<b>(<%= hotcount %>)</b></span>
</div>
</div>
</div>
</script>

此时就可以书写程序:

<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="js/underscore-min.js"></script>
<script type="text/javascript">
//得到模板字符串
var template_str = $("#feeds_template").html();
//生成编译函数
var compiled = _.template(template_str);
//发出Ajax请求,请求字典
$.get("json/baijia0.txt",function(data){
//转为obj对象
dataobj = typeof data == "object" ? data : eval("(" + data + ")");
//遍历数组,得到20本字典。分别数据绑定,分别上树
_.each(dataobj.data.list , function(dictionary){
//数据绑定
var str = compiled(dictionary);
//上树
$(str).appendTo(".main_news")
});
});
</script>

模板修正

模板中存放的是 m_writer_account_type: "0" 或者"2"

此时我们要变为v图标是否显示,就可以写程序:

//发出Ajax请求,请求字典
$.get("json/baijia0.txt",function(data){
//转为obj对象
dataobj = typeof data == "object" ? data : eval("(" + data + ")");
//遍历数组,得到20本字典。分别数据绑定,分别上树
_.each(dataobj.data.list , function(dictionary){
//数据绑定
var str = compiled(dictionary);
//把字符串变为DOM
var $dom = $(str);
//上树
$dom.appendTo(".main_news")
//选择显示和隐藏这个v
if(dictionary.m_writer_account_type == "0"){
$dom.find(".v").show();
}else{
$dom.find(".v").hide();
}
});
});

有些时候我们甚至可以补充key:

_.each(dataobj.data.list , function(dictionary){
//模板修正
dictionary.biaoqian = "么么哒";
//数据绑定
var str = compiled(dictionary);
//把字符串变为DOM
var $dom = $(str);
//上树
$dom.appendTo(".main_news")
//选择显示和隐藏这个v
if(dictionary.m_writer_account_type == "0"){
$dom.find(".v").show();
}else{
$dom.find(".v").hide();
}
});

子模板

来看百度百家的实际应用,此时JSON里面又有一个数组,需要遍历:

需要生成:

<div class="feeds __web-inspector-hide-shortcut__">
<div class="pic">
<a href="http://liukuang.baijia.baidu.com/article/702650">
<img src="http://h.hiphotos.baidu.com/news/crop%3D0%2C1%2C590%2C354%3Bw%3D638/sign=bd98abbaad0f4bfb989fc4143e7f54c1/b3fb43166d224f4a1f3eb73600f790529822d174.jpg" alt="">
</a>
</div>
<div class="feed_main">
<h3>
<a href="http://liukuang.baijia.baidu.com/article/702650">
从混战到三足鼎立,外卖O2O下一个谁先出局?
</a>
</h3>
<p class="summary">
外卖O2O市场份额显示出:三强称霸整个市场的局面越来越明显。那么,从上半场的混战走向如今的三足鼎立,到了外卖O2O三国战的下半场,又将是怎样的格局?
</p>
<div class="info">
<span class="writer">刘旷</span>
<span><img class="v" src="data:images/v.png" alt=""></span>
<span class="time">10:25</span>
<span class="yuedu">阅读<b>(642)</b></span>
<span class="labels">
<a href="http://baijia.baidu.com/?tn=listarticle&amp;labelid=19240">外卖O2O</a>
<a href="http://baijia.baidu.com/?tn=listarticle&amp;labelid=10595">市场</a>
</span>
</div>
</div>
</div>

此时方法1,就是DOM法:

// 发出Ajax请求,请求字典
$.get("/json/baijia0.txt",function(data){
var dataobj = typeof data == "object" ? data : eval("(" + data + ")");
var list = dataobj.data.list;
//each函数会遍历list数组,会让list中的每一项注入到函数中成为实参
_.each(list,function(dictionary){
//数据绑定
var feedStr = feed_compiled(dictionary);
//转为DOM元素
var $dom = $(feedStr);
//上树
$dom.appendTo(".main_news");
//决定v是否显示
if(dictionary.m_writer_account_type != "0"){
$dom.find(".v").hide();
}
//上标签
for(var i = 0 ; i < dictionary.m_label_names.length ; i++){
$("<a href='http://baijia.baidu.com/?tn=listarticle&labelid=" + dictionary.m_label_names[i].m_id + "'>" + dictionary.m_label_names[i].m_name + "</a>").appendTo($dom.find("span.labels"));
}
});
});

方法2子模板,我们有了模板之后,就再也不要去拼接字符串了!

<script type="text/template" id="labels_template">
<a href="http://baijia.baidu.com/?tn=listarticle&labelid=<%=m_id%>"><%= m_name %></a>
</script>
<script type="text/javascript">
// 得到模板字符串
var feed_template_str = $("#feed_template").html();
var labels_template_str = $("#labels_template").html();
// 模板编译函数
var feed_compiled = _.template(feed_template_str);
var labels_compiled = _.template(labels_template_str); // 发出Ajax请求,请求字典
$.get("/json/baijia0.txt",function(data){
var dataobj = typeof data == "object" ? data : eval("(" + data + ")");
var list = dataobj.data.list;
//each函数会遍历list数组,会让list中的每一项注入到函数中成为实参
_.each(list,function(dictionary){
//feed模板数据绑定
var feedStr = feed_compiled(dictionary);
//转为DOM元素
var $dom = $(feedStr);
//上树
$dom.appendTo(".main_news");
//决定v是否显示
if(dictionary.m_writer_account_type != "0"){
$dom.find(".v").hide();
}
//设置labels
for(var i = 0 ; i < dictionary.m_label_names.length ; i++){
var aStr = labels_compiled(dictionary.m_label_names[i]);
$dom.find("span.labels").append($(aStr));
}
});
});
</script>

模板引擎原理及underscore.js使用的更多相关文章

  1. JavaScript模板引擎原理

    JavaScript模板引擎原理,几行代码的事儿 2013-12-03 16:35 by BarretLee, 650 阅读, 6 评论, 收藏, 编辑 一.前言 什么是模板引擎,说的简单点,就是一个 ...

  2. 写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)

    前些时间在看创智博客韩顺平的Smarty模板引擎教程,再结合自己跟李炎恢第二季开发中CMS系统写的tpl模板引擎.今天就写一个迷你版的Smarty引擎,虽然说我并没有深入分析过Smarty的源码,但是 ...

  3. smarty模板引擎原理解析

    //php 控制器文件 <?php//引入模板引擎文件include("20130304.php");$smarty =newTinySmarty();$qq_numbers ...

  4. knockout.js模板绑定之利用Underscore.js模板引擎示例

    View代码 <h1>People</h1> <ul data-bind="template: { name: 'peopleList' }"> ...

  5. JavaScript模板引擎原理,几行代码的事儿

    一.前言 什么是模板引擎,说的简单点,就是一个字符串中有几个变量待定.比如: var tpl = 'Hei, my name is <%name%>, and I\'m <%age% ...

  6. 高性能JavaScript模板引擎原理解析

    随着 web 发展,前端应用变得越来越复杂,基于后端的 javascript(Node.js) 也开始崭露头角,此时 javascript 被寄予了更大的期望,与此同时 javascript MVC ...

  7. 使用新一代js模板引擎NornJ提升React.js开发体验

    当前的前端世界中有很多著名的开源javascript模板引擎如Handlebars.Nunjucks.EJS等等,相信很多人对它们都并不陌生. js模板引擎的现状 通常来讲,这些js模板引擎项目都有一 ...

  8. Smarty模板引擎原理概述

    smarty(模板引擎,模板技术) 使用smarty主要是为了实现逻辑和外在内容的分离: 特点: 1.速度快(因为第二次执行的时候使用第一次执行时生成的编译文件) 2.缓存技术(正是因为缓存技术,使得 ...

  9. js数据绑定(模板引擎原理)

    <div> <ul id="list"> <li>11111111111</li> <li>22222222222< ...

随机推荐

  1. wampserver切换php版本问题

    安装的wampserver有两个php版本,一个5.6的.一个7.1的,之前一直使用的php5.6的版本,今天切换7.1版本,切换成功了 phpinfo显示的版本也是7.1,但是php -v显示的却始 ...

  2. 解决Eclipse导入Gradle项目时在 Building gradle project info 一直卡住

    问题描述 在使用 Eclipse 导入 Gradle 项目时一直卡住,不能导入项目 问题解决   解决办法主要有两种:一是直接下载 gradle 离线包,二是修改项目的 ..\gradle\wrapp ...

  3. spring /* 和 /** 的 区别。

    例如 /** 拦截 /index/1   和  /index /* 代表 /index/1 而  /index 则不会被拦截

  4. angular学习笔记【ng2-charts】插件添加

    原文:https://segmentfault.com/a/1190000008077830 1. 安装 ng2-charts npm install ng2-charts --save2. 还必须引 ...

  5. 08-图8 How Long Does It Take (25 分

    Given the relations of all the activities of a project, you are supposed to find the earliest comple ...

  6. 去除 Git 安装后的右键菜单

    64位 windows 8.1 安装 Git 后,右键菜单多了3个选项(Git Init Here,Git Gui, Git Bash),但是用不着,需要删掉.方法如下: 1.在 CMD 中进入 Gi ...

  7. Abp 添加阿里云短信发送

    ABP中有短信发送接口ISmsSender public interface ISmsSender { Task<string> SendAsync(string number, stri ...

  8. Murano简介

    Project Mission The mission for this project is to provide a way to make third-party applications an ...

  9. /sbin/int的启动及后续进程的启动_3

    转载自: http://www.ruanyifeng.com/blog/2013/08/linux_boot_process.html 半年前,我写了<计算机是如何启动的?>,探讨BIOS ...

  10. 批量 多个JPG生产PDF .net C#

    using iTextSharp.text; using iTextSharp.text.pdf; using System; using System.Collections.Generic; us ...