轻量化模板Handlebars表达式和代码助手

最近在熟悉Handlebars,使用时代码助手还是挺方便的,稍微写了几个示例熟悉下语法。

表达式语法

  Handlebars能解析模板字符串,同时利用解析完的模板函数配合输入对象进行转义输出
  下面用这个鱼价对象做个示例

var data = {
    title: "鱼价表",
    fish:[{
            name: '蝌蚪',
            price: '100',
            alive: true
        },{
            name: "青蛙",
            price: '120',
            alive: false
        },{
            name: '竹荚鱼',
            price: '150',
            alive: true
        },{
            name: '鲫鱼',
            price: '160',
            alive: false
        },{
            name: '雅罗鱼',
            price: '240',
            alive: true
        },{
            name: '鲈鱼',
            price: '400',
            alive: true
        }
    ],
    place:[
        "池塘",
        "大海",
        "小河"
    ],
    version: "test 1.05"
}

  为了方便,直接在浏览器中编写模板

        <script type="text/x-handlebars-template" id="test_expression">
            <h2>{{title}}</h2>
        </script>

  这边设置脚本标签type为 text/x-handlebars-template ,主要是为了区别模板代码和普通脚本,实际不设置type属性也可。

  JS文件中进行模板的解析和数据内容的输入:

    var target = document.getElementById("test_expression").innerHTML
    var template = Handlebars.compile(target)
    var html = template(data) 
	document.getElementById("title_content").innerHTML = html

  利用Handlebars.compile方法进行模板代码的解析,返回函数对象。将输入数据对象作为参数,利用该函数即可完成转义,之后替换对应的html文本即可。

  输出效果如图:
        在这里插入图片描述

内置代码助手

  Handlebars通过代码助手来实现复杂的显示逻辑,按需求加载模板。常用的内置代码模板包括each,if-else等,下面来使用下这两种常用的代码助手。

(1)each
  each也是顾名思义在模板中对数据进行一个迭代操作,常见的使用情景为生成table表等。下面用它来输出对应的鱼价表。
  首先设置模板代码:

	        {{#each fish}}
                <tr>
                    <td>{{name}}</td>
                    <td>{{price}}</td>
                </tr>
            {{/each}}

  Html:

			<div>
                <table id="table_content"></table>
            </div>

  Js:

    //利用模板替换table
    var table_target = document.getElementById("test_table_template").innerHTML
    var template2 = Handlebars.compile(table_target)
    var html2 = template2(data)
    document.getElementById("table_content").innerHTML = html2

  输出结果:
        在这里插入图片描述

  代码助手的使用格式为{{#助手名 输入对象名}}_ 具体内容 {{/助手名}},用each遍历模板代码很直观,挺好。

(2)If-else
  If判断也是最基本的,其还能与else进行联合使用。下面用改助手进行活鱼的输出。
  设置模板代码:

	    <script type="text/x-handlebars-template" id="test_table_template2">
            {{#each fish}}
                {{#if alive}}
                	<tr>
                        <td>{{name}}</td>
                        <td>{{price}}</td>
                    </tr>
                {{/if}}
            {{/each}}
        </script>

  Html:

	        <div>
                <table id="table_content2"></table>
            </div>

  JS:

//利用if-else进行内容筛选
    var table_target1 = document.getElementById("test_table_template2").innerHTML
    var template3 = Handlebars.compile(table_target1)
    var html3 = template3(data)
    document.getElementById("table_content2").innerHTML = html3

  输出结果:
        在这里插入图片描述

  这部分在模板代码中利用if助手进行alive的判断,最终输出活鱼结果,方便。

自定义助手代码

  可以看出,Handlebar中代码助手可以用来实现模板显示逻辑的编写,但内置助手的功能太过简单,满足不了一般的需求。比如if-else原生助手只能判断输入属性的true和false来进行判断控制,甚至简单的数值比较判断也做不到,这时候就需要自定义代码助手。
下面实践来写一个大于判断助手。
  JS中注册自定义代码助手:

//自定义代码助手
Handlebars.registerHelper("bigger", function(x1, x2, options){
    if(x1 > x2){
        //执行模板渲染
        return options.fn(this)
    }else{
        //跳过
        return options.inverse(this)
    }
})

  可以看到,利用registerHelper函数进行注册。参数为代码助手名称(也就是模板代码中使用的名称)以及具体方法。在我们的bigger助手中,方法有三个参数,x1与x2是输入,option参数为隐含参数,用来调用Handlebars的处理方法,在模板代码中不用写。
重要方法为option.fnoption.inverse,分别为返回上下文和什么都不做跳过。此时this为上下文中内容,如当前迭代数组中对应的迭代值等。

  模板代码:

        <script type="text/x-handlebars-template" id="test_table_template3">
                {{#each fish}}
                    {{#bigger price 100}}
                    <tr>
                        <td>{{name}}</td>
                        <td>{{price}}</td>
                    </tr>
                    {{/bigger}}
                {{/each}}
        </script>

  此处意图输出100以上价格的鱼列表,参数设置为price和100,即为上文的x1,x2。之后利用js编译模板输出html即可。

  输出结果:
        在这里插入图片描述

  顺便介绍下另一个重要方法Handlebars.SafeString,该方法能返回安全的字符串,防止代码的注入等导致的安全问题,在返回字符串时尽量都选用这个方法。
  做一个大写输出的示例:

Handlebars.registerHelper("upper", function(options){
    var upperContent = options.fn(this).toUpperCase()
    return new Handlebars.SafeString('<p>'+upperContent+'</p>')
})

hash功能

  这边说的hash功能其实是对自定义代码助手的一种拓展,通过设置属性来实现更广泛的控制功能。比如上文中我们实现了一个大于bigger助手,那么通过hash属性设置就能通过控制属性来实现一个通用的比较代码助手。
  Js注册:

//带hash属性
Handlebars.registerHelper("compare", function(x1, x2, options){
    var type = options.hash["type"]
    if(type == 'up'){
        if(x1 > x2){
            //执行模板渲染
            return options.fn(this)
        }else{
            //跳过
            return options.inverse(this)
        }
    }else if(type == 'down'){
        if(x1 < x2){
            //执行模板渲染
            return options.fn(this)
        }else{
            //跳过
            return options.inverse(this)
        }
    }
})

  模板代码:

        <script type="text/x-handlebars-template" id="test_hash">
            {{#each fish}}
                {{#compare price 150 type="down"}}
                <tr>
                    <td>{{name}}</td>
                    <td>{{price}}</td>
                </tr>
                {{/compare}}
            {{/each}}
        </script>

  在函数中使用options.hash就能获取模板中的hash参数。该方法中设置一个type参数,用它来进行大于小于的修改,此时功能是输出价格低于150的鱼价列表。

  输出结果:
在这里插入图片描述

代码块参数

  3.0之后新功能,能从助手代码中接收命名参数。
  示例:

		<script type="text/x-handlebars-template" id="test_param">
            {{#each fish as |fishs fishId|}}
                <tr>
                    <td>{{fishId}}</td>
                    <td>{{fishs.name}}</td>
                    <td>{{fishs.price}}</td>
                </tr>
            {{/each}}
        </script>

  此时fishId为当前迭代对象的序号。
  输出结果:
        在这里插入图片描述

总结

  Handlebars能实现模板复用,代码助手实现页面逻辑。
  比如Ajax获取JSON数据后解析成对象,直接输入模板即可,减少了页面的重复工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值