介绍一款js模版引擎handlebars

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>
// 一个判断字符串是否相等的方法equals
Handlebars.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功能基本介绍完毕,如果有新的应用我会及时更新,也请大家多多指教。


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生(FS)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值