zoukankan      html  css  js  c++  java
  • 模板引擎原理及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 %>" 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="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="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>
  • 相关阅读:
    使用Docker-compose部署MySQL测试环境
    使用MySQL SQL线程回放Binlog实现恢复
    MySQL 插件之 连接控制插件(Connection-Control)
    sysbench工具使用
    故障分析--主从复制故障1
    MySQL性能指标计算方式
    AJAX的 同步异步;EZView.js 图片预览和pdf预览
    Caused by: java.lang.ClassNotFoundException: org.springframework.context.App
    解决Myeclipse或Eclipse出现JPA project Change Event Handler问题的解决办法
    java中转换为string的方法;eques和==区别
  • 原文地址:https://www.cnblogs.com/-liujia/p/9352069.html
Copyright © 2011-2022 走看看