模板引擎原理及underscore.js使用

为什么要使用模板引擎

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 %>"  />
            </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="images/v.png"  /></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();
    }
});

子模板

p.p1 { margin: 0.0px 0.0px 3.1px 0.0px; text-align: justify; font: 10.5px "Songti SC"; color: #000000 }
span.s1 { }
span.s2 { font: 10.5px "Times New Roman" }

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

p.p1 { margin: 0.0px 0.0px 3.1px 0.0px; text-align: justify; font: 10.5px "Songti SC"; color: #000000 }
span.s1 { }

需要生成:

<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="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>

p.p1 { margin: 0.0px 0.0px 3.1px 0.0px; text-align: justify; font: 10.5px "Songti SC"; color: #ff0000 }
span.s1 { }
span.s2 { font: 10.5px "Times New Roman" }

此时方法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"));
        }
    });
});

p.p1 { margin: 0.0px 0.0px 3.1px 0.0px; text-align: justify; font: 10.5px "Songti SC"; color: #000000 }
span.s1 { color: #ff0000 }
span.s2 { font: 10.5px "Times New Roman"; color: #ff0000 }
span.s3 { }

方法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>

原文地址:https://www.cnblogs.com/-liujia/p/9352069.html

时间: 2024-10-09 11:18:35

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

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

JavaScript模板引擎原理,几行代码的事儿 什么是模板引擎,说的简单点,就是一个字符串中有几个变量待定.比如: var tpl = 'Hei, my name is <%name%>, and I\'m <%age%> years old.'; 通过模板引擎函数把数据塞进去, var data = { "name": "Barret Lee", "age": "20" }; var result

JavaScript模板引擎原理与用法

这篇文章主要介绍了JavaScript模板引擎原理与用法,结合实例形式详细分析了javascript模版引擎相关概念.原理.定义及使用方法,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下 一.前言 什么是模板引擎,说的简单点,就是一个字符串中有几个变量待定.比如: var tpl = 'Hei, my name is <%name%>, and I\'m <%age%> years old.'; 通过模板引擎函数把数据塞进去, var data = { &q

smarty模板引擎原理解析

//php 控制器文件 <?php//引入模板引擎文件include("20130304.php");$smarty = new TinySmarty();$qq_numbers=array('a1'=>'12333','a2'=>'2222222','a3'=>'333333','a4'=>'3333333');$smarty->assign($qq_numbers);$smarty->assign('title','这是我的QQ号码');$

js模板引擎原理,附自己写的简洁模板引擎

js处理DOM交互非常普遍,但DOM结构单纯用js字符串拼接简直难以维护,不方便理解和扩展. 下面展现了js模板引擎的实现原理: html中的模板 <script id="mytpl"> <div> 我的名字是:$name$ <br/> 今年$age$了! </div> </script> 因为script不会被浏览器解析和渲染,最大限度节省了浏览器资源,textarea标签同样可以达到效果.Template标签就是这样的目的

Trimpath Template 及JS模板引擎原理

这个是一个很老的JS模板引擎.看了下源码,理解下模拟条件语句的替换原则.感觉有点复杂~ 简记之. 如果不涉及条件语句,可以直接在代码里构建模板,ajax请求回来的数据套用即可.最原始方式. Trimpath JavaScript 是个轻量级的,基于JavaScript的,跨浏览器,采用APL/GPL开放源代码协议的,可以让你轻松进行基于模板编程方式的纯JS引擎. 它有如下的特点: 1.采用标准的JavaScript编写,支持跨浏览器 2.模板语法类似于:FreeMarker,Velocity,S

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

随着 web 发展,前端应用变得越来越复杂,基于后端的 javascript(Node.js) 也开始崭露头角,此时 javascript 被寄予了更大的期望,与此同时 javascript MVC 思想也开始流行起来.javascript 模板引擎作为数据与界面分离工作中最重要一环,越来越受开发者关注,近一年来在开源社区中更是百花齐放,在 Twitter.淘宝网.新浪微博.腾讯QQ空间.腾讯微博等大型网站中均能看到它们的身影. 本文将用最简单的示例代码描述现有的 javascript 模板引擎

php模板引擎原理

模板引擎实现的原理 访问php文件, php文件会去加载模板引擎,通过模板引擎去加载模板然后替换模板里面的变量 然后生成一个编译文件 最后将该编译文件导入 访问的php文件中输出 第二次访问的时候 如果 缓存文件存在或者没有被改动则直接 导入缓存文件 输出 否则重新编译 自定义的一个模板引擎 mytpl.class.php <?php class mytpl{ //指定模板目录 private $template_dir; //编译后的目录 private $compile_dir; //读取模

tornado模板引擎原理

前言 老师问小明:已经a=1, 求a+1的值. 小明挠挠头,思考后回答:老师,a+1的结果是2. 以上是一个非常简单的例子,实际上就是一个模板编译过程. a=1,表示一个命名空间(namespace)中的一项,该命名空间中存在一个名称(name)为a,其值为1.在python里面,命名空间可以用数据结构字典来表示. a+1,实际上是一个非常简单的模板.这个模板里面有且只有一条规则a+1.本博文中所说的模板,实际上更类似一份空白的数学考卷.这份数学考卷中,有很多类似上面老师问小明的题目. 学生解决

&lt;Ajax&gt; 七. 模板引擎的使用(template-web.js的使用)

<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <title>Title</title> </head> <body> <h3>模板引擎的使用</h3> </body> </html> <!-- 模板 --> <!-- 引入模板引擎js --> <scrip