使用EJS(模板引擎)动态绑定页面中的数据

本文介绍了前端动态绑定页面数据的两种方法:JS字符串拼接和使用模板引擎,重点讲述了EJS模板引擎的工作原理和客户端使用步骤,包括导入EJS、准备数据、设定模板和嵌入数据以及在JS中提供绑定数据。EJS简化了字符串拼接,提高了代码可维护性和性能。

前端主要的绑定页面中的数据的方式有两种:

1.JS代码中进行字符串拼接 

2.使用模板引擎(Mustache.js  或者 ejs.js) 来动态绑定页面中的数据

 

一、JS代码中进行字符串拼接 

这种方式属于完全的前后端分离,在JS中获取到服务器端返回的数据后,把之前在HTML页面中写好的标签,一句句的复制到JS中,用字符串拼接的方式,把标签和数据拼接在一起,最后再把拼接完成的字符串插入到页面中指定的位置。使用这种方式处理简单的字符串拼接还可以,处理复杂的,非常的恶心,我们接下来看一下:

var str = '';
if (jsonData) {
    var data = jsonData["data"];
    $.each(data, function (key, curAry) {
        str += '<div class="matchDate" time="' + key + '">';
        str += '<h2 class="date">' + key.myFormatTime("{1}月{2}日") + '</h2>';
        str += '<ul class="matchList">';
            $.each(curAry, function (index, curData) {
                var linkURL;
                str += '<li>';
                    str += '<div class="left">';
                        str += '<span class="time">' + curData["startTime"].myFormatTime("{3}:{4}") + '</span>';
                        str += '<span class="type">' + curData["matchDesc"] + '</span>';
                        str += '</div>';
                    str += '<div class="middle">';
                str += '</li>';
            });
            str += '</ul>';
        str += '</div>';
    });
}
$match.children("div").eq(0).html(str);
$myScroll.refresh();

这样,不仅拼接字符串的时候浪费时间,后期改动的话也不好改,而且JS代码会非常的混乱; 此外我看了一些项目中,还有使用动态创建元素节点来实现的,这样做和字符串拼接一样,JS中的代码混乱,不易于后期的维护,此外使用动态创建元素节点的方式,还会引发多次的DOM回流,影响页面的性能。

 

二、使用模板引擎绑定和渲染数据

模板引擎的原理其实也是字符串拼接,但是和第一种不同的是,它不是把字符串在JS代码中拼接,而是先在HTML页面中,按照模板提供的规则把数据内容嵌入到HTML标签中。最后由模板解析成需要的字符串,在JS中把解析出来的字符串放入到页面中的指定位置进行渲染。

目前市面上流行的模板很多很多,例如: kTemplate、jade、dot、angular中也提供模板,以及我们今天需要讲解的EJS等。

EJS

EJS(Embedded JavaScript)也是众多模板中的一种,它主要是NODE开源的模板,在NODE环境下实现绑定和渲染的。但是它也可以单独的在客户端调取使用,我们接下来就介绍独立在客户端的使用,在NODE中如何的使用请看后续的NODE的课程。

在客户端使用EJS主要是分四步:

1、导入EJS

EJS的源码大家可以去它的官网进行下载: http://www.embeddedjs.com/

<script charset="UTF-8" type="text/javascript" src="js/ejs.min.js"></script>

2、准备需要绑定的数据

在真实的项目中,这一步需要使用AJAX或者JSONP等技术从服务器获取,然后把获取回来的数据进行解析重构(一般情况下也不需要二次重构数据结构)。

 

//->使用jQuery的AJAX获取数据
$.ajax({
    url: '/getMenu',
    type: 'get',
    dataType: 'json',
    success: function (data) {
        //-> data: 就是我们从服务器获取的数据,然后执行第四步的bindHTML方法
        bindHTML(data);
    }
});


//->假设我们获取的数据格式如下
[
    {
        "name": "NBA",
        "tag": "nba",
        "columnId": 100000
    },
    {
        "name": "欧洲杯",
        "tag": "ec",
        "columnId": 3
    },
    {
        "name": "中超",
        "tag": "csl",
        "columnId": 208
    }
    ...
]

3、在HTML页面中设定模板和嵌入数据

模板有自己的渲染规则,我们把需要写的JS循环判断放在 <%%>中,如果需要输出用<%%>;其实非常的简单就是把之前字符串拼接方式中的JS写在了HTML中,这样EJS负责把模板中的内容获取到,然后按照规则把数据和HTML标签拼接在一起。

//->这个是最终显示HTML和数据的区域
<div class="menu"></div>


//->这个是制定的模板
<script charset="UTF-8" type="text/template" id="menuTemplate">
    <% if (data && data.length > 0) { %>
    <ul>
        <% data.forEach(function(curData, index) { %>
        <% var cName=index === 0 ? 'bg' : null; %>
        <li class="<%=cName%>">
            <a href="#<%=curData.tag%>" columnId="<%=curData.columnId%>">
            <%=curData.name%>
            <i class="triangle">
                <span class="triLeft"></span>
                <span class="triRight"></span>
            </i>
            </a>
        </li>
        <% }); %>
    </ul>
    <% } %>
</script>

 

4、在JS中为EJS模板提供需要绑定的数据

function bindHTML(data) {
    //->首先把页面中模板的innerHTML获取到
    var str = $("#menuTemplate").html();

    //->然后把str和data交给EJS解析处理,得到我们最终想要的字符串
    var result = ejs.render(str, {data: data});

    //->最后把获取的HTML放入到MENU中
    $(".menu").html(result);
}

以上就是EJS独立在客户端的使用,其它的模板引擎和其类似,区别在于模板中的嵌入数据和编写JS的语法不一样,例如:EJS是<%%>操作,而dot是{{}}这样操作,angular也有自己的操作规则。

 

三、Zepto.js 的AJAX 常见开发模式

这种是单例模式

//->MATCH INFO
var matchRender = (function () {

    var $matchInfo = $('.matchInfo'),                     //获取容器
        $matchInfoTemplate = $('#matchInfoTemplate');     //获取模板


    //->BIND HTML
    function bindHTML(matchInfo) {
        //->使用ejs模板引擎
        $matchInfo.html(ejs.render($matchInfoTemplate.html(), {matchInfo: matchInfo}));
    }

    return {
        /* init 是当前的入口 */
        init: function () {
            //->GET DATA
            $.ajax({
                url: 'http://matchweb.sports.qq.com/html/matchDetail?mid=100000:1468531&_=1472982271063&callback=jsonp1',
                dataType: 'jsonp',
                success: function (result) {
                    if (result && result[0] == 0) {
                        result = result[1];
                        var matchInfo = result['matchInfo'];
                        matchInfo['leftSupport'] = result['leftSupport'];
                        matchInfo['rightSupport'] = result['rightSupport'];

                        //->BIND HTML
                        bindHTML(matchInfo);

                    }
                }
            });
        }
    }
})();
matchRender.init();

 

或者这样写

 

webapp HTML页面

<!-- MATCH LIST -->
<section class="matchList">
    <ul class="clearfix">
        
    </ul>
</section>



<script charset="UTF-8" type="text/javascript" src="static/js/zepto.min.js"></script>
<script charset="UTF-8" type="text/javascript" src="static/js/touch.js"></script>
<script charset="UTF-8" type="text/javascript" src="static/js/ejs.js"></script>

<!-- matchList模板-->
<script charset="UTF-8" type="text/template" id="matchListTemplate">
    <% $.each(matchList, function(index, item) { %>
    <li class="<%= index===0?'bg':'' %>">
        <a href="#">
           <div>
               <img src="<%= item.pic %>" alt="">
               <span><%= item.duration.substring(item.duration.indexOf(':')+1) %></span>
           </div>
           <p><%= item.title %></p>
        </a>
    </li>
    <% }) %>
</script>


 

请求回的数据结构

请求回的数据结构

JS

//->MATCH LIST
var matchListRender = (function () {

    //->以后jQuery也是这么用
    //->获得容器
    var $matchList = $('.matchList'),
        $matchListUL = $matchList.children('ul'),
        $matchListTemplate = $('#matchListTemplate');  //获取模板

    //->BIND HTML
    function bindHTML(matchList) {
        $matchListUL.html(ejs.render($matchListTemplate.html(), {matchList: matchList})).css('width', parseFloat(document.documentElement.style.fontSize) * 2.4 * matchList.length + 20 +  'px');

        //->处理谷歌浏览器不能滚动的问题
        document.querySelector('.matchList').addEventListener('touchmove', function (e) {
            e.preventDefault();
        });

        //->实现局部滚动
        new IScroll('.matchList', {
            scrollX: true,
            scrollY: false,
            click: true  //允许点击<a>链接
        });
    }

    return {
        init: function () {
            $.ajax({
                url: 'http://matchweb.sports.qq.com/html/matchStatV37?mid=100002:2365',
                dataType: 'jsonp',
                success: function (result) {
                    if (result && result[0] == 0) {
                        result = result[1]['stats'];
                        var matchList = null;
                        $.each(result, function (index, item) {
                            if (item['type'] == 9) {
                                matchList = item['list'];
                                return false;  //结束$.each 这个循环
                            }
                        });

                        //->BIND HTML
                        bindHTML(matchList);
                    }
                }
            });
        }
    }
})();
matchListRender.init();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值