• 模板引擎原理及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>
  • 相关阅读:
    webdav srs相关
    How To Configure WebDAV Access with Apache on Ubuntu 14.04
    ubuntu 编译lighttpd
    srs编译及推流测试
    Compile pciutils (lspci, setpci) in Windows x86,在 Windows x86 平台下编译 pciutils (lspci, setpci)
    mingw MSYS2 区别
    Qt之美(三):隐式共享
    Qt之美(二):元对象
    Qt之美(一):d指针/p指针详解
    C++的栈空间和堆空间
  • 原文地址:https://www.cnblogs.com/-liujia/p/9352069.html
Copyright © 2020-2023  润新知