介绍一款js模版引擎handlebars

来源:互联网 发布:k-means聚类算法python 编辑:程序博客网 时间:2024/06/06 02:25

handlebars不算什么新技术,但是确实是一款非常好用的模版引擎,初次使用,这里做一下总结,对于不认这个东西朋友们,他是个什么东西呢?

这里我就说一个我们经常遇到的情况,在系统开发的过程中,我们经常要写异步请求,然后拿到json数据,之后在js中写一大坨html代码拼接上json数据,然后通过jquery的方法动态加载到页面上。

上面说的情况作为程序员大家肯定都遇到过也都做过,其中的痛苦之处大家都懂,尤其是有错误回来检查的时候,看着那一大坨代码真心恶心,那么handlebars就是来解决这个问题的。

他首先可以在页面上定义一个html代码的模版,然后,经过很简单步骤就可以实现上述效果了,而且修改起来so esay! look code!

1.首先需要引入这两个js包,因为handlebars也是基于jquery的,jquery的强大之处毋庸置疑。

<script type="text/javascript" src="script/jquery.js"></script><script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>

2.定义一个模版,并且准备引擎处理完的代码放到哪里,这里定义一个巨简单的模版方便理解

<%-- Handlebars处理完的代码放到这个div中 --%><div id="description"></div><%-- Handlebars.js模版 --%><%-- Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句 --%><%-- id可以用来唯一确定一个模版,type是模版固定的写法 --%><script id="description-template" type="text/x-handlebars-template">    <table>        {{#each userList}}        <tr>            <td>{{username}}</td>            <td>{{password}}</td>        </tr>        {{/each}}    </table></script>

3.下面是js调用模版进行一些处理的代码

<script>$(window).load(function() {    var config = {            "url" : "/user/userList.json",// json请求的地址            "params" : {// json请求的参数信息, 没有的话可以不设置这个属性,或者是 {}空对象                "shopId" : 1            },            "renderTemplateSelector" : "#description-template",// 模板            "renderToSelector" : "#description",// 你要把处理后的代码设置到哪个元素中            "beforeRenderjsonDataEvent" : function(jsonData) {// 渲染handlebars数据之前 做了什么                // TODO            },            "afterRenderjsonDataEvent" : function(jsonData) {// 渲染handlebars数据之后 做了什么                // TODO            }            "parseRenderjsonData" : function(jsonData) {// 渲染handlebars需要的数据,此处 jsonData是从后端返回的json数据                return {                    "userList" : jsonData  // 注意这里的userList与你模版中用的userList是同一个东西,当然这里可以return多个值,以应对不同的需求,在模版中都可以通过userList同样的方式去使用。                };            }        };        loadJsonAndRenderTemplateHtmlToSelector(config);});// 这个方法是封装过的方法以便实现更多功能,比如渲染前需要执行什么方法,渲染后需要执行什么,稍微看下就能看懂的function loadJsonAndRenderTemplateHtmlToSelector(config) {    // 执行ajax请求    $.post(config.url, config.params, {        success : function(jsonData) {            // 判断ajax返回的数据有没有问题            if (null != jsonData && "" != jsonData && !$.isEmptyObject(jsonData)) {                console.log("return jsonData:%o", jsonData);                var canRender = true;                // 渲染handlebars数据之前 做了什么                if ($.isFunction(config.beforeRenderjsonDataEvent)) {                    // 渲染前,调用该方法,该方法可以通过返回true或者false来决定是否继续渲染                    canRender = config.beforeRenderjsonDataEvent(jsonData);                }                // 支持在 beforeRenderjsonDataEvent 返回是否可以渲染                if (!canRender) {                    return;                }                // 渲染                var commentTemplate = Handlebars.compile($(config.renderTemplateSelector).html());                renderTemplateHtmlToSelector(config.renderToSelector, config.parseRenderjsonData(jsonData), commentTemplate);                // 渲染handlebars数据之后 做点什么                if ($.isFunction(config.afterRenderjsonDataEvent)) {                    config.afterRenderjsonDataEvent(jsonData);                }            } else {                console.warn("[%o] jsonData is null or empty,nothing to do!!!", config.renderToSelector);            }        }    }, {        error : function(jsonData) {            console.log(jsonData);        }    });}/** * 渲染 handlebarsTemplate *  * @param selector *                要渲染的选择器 * @param data *                数据 数据格式 { "title" : "xxxx", "recommendationEngineCommandList" : xxxx } *  * @param template *                模板 */function renderTemplateHtmlToSelector(selector, data, template) {    var html = template(data);    console.log("selector:%o,html:%o", selector, html);    // 将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。    $(selector).html(html);}</script>

至此,handlebars的基本功能和应用场景大家应该能够理解了。

4.扩展一些handlebars模版中常用到的操作

// 其实handlebars中比较好用的方法不多,他提倡的是自己写方法实现,但还是介绍下我较常用的。// 如果XXX不是对象而是数组的话,可以直接下面的用法,如果是对象的话,上面的例子已经介绍过了使用方法。{{#each XXX}} <li>{{this}}</li> {{each}}// 如果XXX是map的话,可以这样用,@key得到的key的值,this得到的是该key的value{{#each XXX}} <li>{{@key}}</li><li>{{this}}</li> {{each}}// 但凡使用each循环的,那么都可以通过@index得到当前循环的下标{{@index}}// handlebars本身是带有if方法的,但是并不推荐用,他的if并不能进行比较,只能判断是否存在,或者true和false,至少我现在是这么理解的,如下{{#if XXX}}{{else}}{{/if}}// 我们一般需求都会比较复杂,所以这里推荐自己注册方法来实现需求,handlebars专门提供了registerHelper用来进行方法的注册,那么如何注册呢,看下面代码。<script>// 一个判断字符串是否相等的方法equalsHandlebars.registerHelper("equals",function(v1, v2, options){        if (v1 == v2) {            return options.fn(this);// 满足添加继续执行        }        return options.inverse(this);// 不满足条件执行{{else}}部分    });// 这是用来比较大小的Handlebars.registerHelper("isBig",function(big,small,options){        if(big > small){            return options.fn(this);// 满足添加继续执行        }        return options.inverse(this);// 不满足条件执行{{else}}部分    });// 这是截取字符串的方法Handlebars.registerHelper("substring",function(str, start, end) {        if(str==null || str=="") {            return str;        }        return str.substring(start,end);    });</script>以上三个方法,应用于模版中的代码如下// 比较"aa"和"bb"是否相等{{#equals "aa" "bb"}}{{else}}{{/equals}}// 比较3是否大于2{{#isBig 3 2}}{{else}}{{/isBig}}// 截取abcdefg字符串{{substring "abcdefg" 2 5}}注意以上的几种使用方式,可以看出,判断true和false的和有return值的写法上不太一样,前者需要“#”后者则不需要。这里说另一种情况,each嵌套的问题,如果要取上一层的对象的属性值,使用../加属性名<script id="table-template" type="text/x-handlebars-template">    {{#each this}}        {{#each info}}            {{../name}}{{this}}<br>        {{/each}}    {{/each}}</script>至此我所了解的handlebars功能基本介绍完毕,如果有新的应用我会及时更新,也请大家多多指教。
1 0
原创粉丝点击