zoukankan      html  css  js  c++  java
  • template7入门教程及对它的一些看法

    template7framework7的内置模板引擎,在此之前使用过jquery-tmpl,不过刚刚打开github看了下,已经停止更新,并且将要被JsRender所替代。妹的,JsRender又是什么鬼啊?扯远了,之前听过别人关于jquery-tmpl模板引擎的技术分享,它的源码加上一堆注释才100多行。在此之前模板给我的概念是jsp那种,要与java后端一起配合使用的,后端用数据模型把值传到前台,前台再通过${}获取值。如果需要进行一些条件判断,则使用jstl。如果前台要异步局部刷新页面,则用ajax来实现,返回的数据以拼字符串的方式把DOM嵌入到原来的页面,但是拼字符串这种方式实在坑爹,不仅写来痛苦,维护起来也痛苦。后来就使用js动态添加HTML,然后再用js把数据填充进去。写法有以下两种:

      <script type="text/html" id="theTemplate">
          <div class="dialog">
            <div class="title">
                <img src="close.gif" alt="点击可以关闭" />亲爱的提示条
            </div>
            <div class="content">
                <img src="delete.jpg" alt="" /><span>您真的要GG吗?</span>
            </div>
            <div class="bottom">
                <input id="Button2" type="button" value="确定" class="btn"/>&nbsp;&nbsp;
                <input id="Button3" type="button" value="取消" class="btn"/>
            </div>
          </div>
      </script>
        
      var template = document.getElementById("theTemplate").innerHTML ;
    

    或:

    <textarea id="theTemplate" style="display:none">
        <div class="dialog">
            <div class="title">
                <img src="close.gif" alt="点击可以关闭" />亲爱的提示条
            </div>
            <div class="content">
                <img src="delete.jpg" alt="" /><span>您真的要GG吗?</span>
            </div>
            <div class="bottom">
                <input id="Button2" type="button" value="确定" class="btn"/>&nbsp;&nbsp;
                <input id="Button3" type="button" value="取消" class="btn"/>
            </div>
          </div>
    </textarea>
    
    var template = document.getElementById("theTemplate").value ;
    

    这种写法优点是:

    1. 比拼字符串优雅很多

    2. 浏览器不会读取到就渲染,所以里面的img的src也不会自动获取

    缺点:

    1. script标签里面不能直接写变量,又需要频繁的操作修改DOM。

    可能是基于以上的缺点,引入了jquery-tmpl模板引擎,但我觉得前端模板的真正意义在于前后端分离,即无法通过controller把数据发送到view,只能以接口请求的形式得到数据,但是HTML本身又没有jstl或freemarker那样获取变量或者进行if判断、each循环的功能,所以,需要有一种工具来进行功能的替代,这时前端模板引擎纷纷出现,五花八门,像我们项目中有用到的underscore.js内置的模板引擎,但是那个功能比较单一,毕竟模板引擎只是他的一部分,功能够用就好。
    而我们今天要说的template7,则是一个功能更为强大,更为全面的模板引擎,官方说它执行速度也很快,但是到底快不快,比哪些快,我没去研究,有兴趣的可以自己拿几种模板引擎对比下。

    Template7还嵌入了handlebars的表达式{{#}}

    
    <div class="list-block">
      <ul>
        {{#each items}}
        <li class="item-content">
          <div class="item-inner">
            <div class="item-title">{{title}}</div>
          </div>
        </li>
        {{/each}}
      </ul>
    </div> 
    

    其实个人不喜欢一个模板搞几种表达式,不过猜测作者应该是考虑到在多种情况下都可以使用,即{{}}可能在当前的上下文中有了其他的用法或者含义,如果我模板也请也使用这个就会产生冲突,至于能有什么用法,不要问我,我不知道,但我知道jquery-tmpl模板中有两种取变量值的写法,${}{{=}}${}的写法是和freemarker、jsp等模板的取值方法是一样的,所以会产生混淆,所以一般用{{=}}

    模板中我们经常能见到的方法,这里就简单的一笔带过,相信看官网的介绍会更加明了。我们就主要说一下不常用的或者其他模板引擎里没有的一些功能。

    Template7有以下表达式语法:

    Variables

    • {{title}} - plain variable. Outputs "title" variable in current context

    • {{../title}} - plain variable. Outputs "title" variable in parent context

    • {{../../title}} - plain variable. Outputs "title" variable in parent context of parent context

    • {{this}} - plain variable. Outputs variable equals to current context

    • {{person.name}} - plain variable. Outputs variable equals to "name" property of "person" variable in current context

    • {{../person.name}} - plain variable. The same but for parent context

    • {{@index}} - access to additional data variable. Such data variables could be used in helpers

    Block expressions

    • {{#each}} - begin of block expression

    • {{else}} - begin of block inverse expression (where supported)

    • {{/each}} - end of block expression

    • {{#each reverse="true"}} - begin of block expression with passed reverse:true hash arguments

    Helpers
    Helpers could be plain expressions and block expressions:

    • {{join myArray delimiter=", "}} - execute "join" helper and pass there "myArray" variable of current context and delimiter:', 'hash argument

    以上比较少见的是{{../title}},{{this}},{{person.name}}{{@index}}这几种写法,那我们就举个栗子(非糖炒)说一下:

    <script id="tmplOne" type="text/template7">
        <p>Hello, my name is {{firstName}} {{lastName}}</p>
        <ul>
            {{#each arr}}
            <li>{{sex}}======={{birthday}}======={{../firstName}}</li>
            {{/each}}
        </ul>
        <p>----------------</p>
        <ul>
            {{#each arr reverse="true"}}
            <li>{{sex}}======={{birthday}}</li>
            {{/each}}
        </ul>    
    </script>
    
     var context = {
                    firstName: 'John',
                    lastName: 'Doe',
                    arr:  [
                        {
                        sex: 'boy',
                        birthday:'1991-1-1'
                        },
                        {
                            sex: 'girl',
                            birthday:'1991-2-2'
                        }
                    ]
                };
        
    输出如下:        
    Hello, my name is John Doe
    boy=======1991-1-1=======John
    girl=======1991-2-2=======John
    ----------------
    girl=======1991-2-2
    boy=======1991-1-1

    到这里想必大家都已经看明白了吧,如果写成下面这样,

    {{#each arr}}
        <li>{{sex}}======={{birthday}}======={{firstName}}</li>
    {{/each}}

    {{firstName}}是无法取到值得,因为当前一级是arr里面,往上一级才能或取到值。

    第二个:

    <script id="tmplOne" type="text/template7">
        <p>Here are the list of people i know:</p>
        <ul>
            {{#each people}}
            <li>{{@index}}======== {{this.test}} ********{{this}}</li>
            {{/each}}
        </ul>
        <p>{{person.name}}</p>
    </script>
    
    var context = {
                    people: ['John Doe', {test:'test'}],
                    person: {
                        name: '虚空假面'
                    }
                };
    //输出结果:
    Here are the list of people i know:
    0======== ********John Doe
    1======== test ********[object Object]
    虚空假面

    下面说一说内置的一些辅助方法:

    {{join myArray delimiter=", "}}

    这个也是很少见到,有什么用,怎么用?
    官方是这么说的:This plain helper will join Array items to single string with passed delimiter

    <p>Genres: {{join genres delimiter=", "}}</p>
    
    {
      genres: ['comedy', 'drama']
    }
    
    输出:
    <p>Genres: comedy, drama</p>

    这个方法有木有很像js中的join()方法,

    <script type="text/javascript">
    var arr = new Array(3)
    arr[0] = "George"
    arr[1] = "John"
    arr[2] = "Thomas"
    document.write(arr.join())
    </script>
    
    输出:
    George,John,Thomas

    其实两者的作用也是一样的,都是把数组对象转成字符串,并用指定符号隔开。

    {{#each}}...{{else}}...{{/each}}

    之前用过{{#if}}...{{else}}...{{/each}},但是见到{{#each}}...{{else}}...{{/each}}感觉一脸懵逼
    看栗子吧:

    <p>Car properties:</p>
    <ul>
        {{#each props}}
        <li>{{@key}}: {{this}}</li>
        {{else}}
        <li>No properties</li>
        {{/each}}
    </ul>
    <p>obj:</p>
    <ul>
        {{#each obj}}
        <li>{{@key}}: {{this}}</li>
        {{else}}
        <li>No properties</li>
        {{/each}}
    </ul>
    <p>exp:</p>
    <ul>
        {{#each exp}}
        <li>{{@key}}: {{this}}</li>
        {{else}}
        <li>No properties</li>
        {{/each}}
    </ul>
    var context = {
                    props: {
                        power: '150 hp',
                        speed: '200 km/h',
                    },
                    obj: {},
                    exp:false
                };
    
    输出:
    Car properties:
    power: 150 hp
    speed: 200 km/h
    
    obj:
    No properties
    
    exp:
    No properties

    这下明白了吧,其实他就下面这种形式的缩写。

    <ul>
        {{#if obj}}
            {{#each obj}}
            <li>{{@key}}: {{this}}</li>
            {{/each}}
        {{else}}
            <li>No properties</li>
        {{/if}}
    </ul>       

    {{#unless}}...{{else}}...{{/unless}}

    这个跟if else相反,没什么好说的,感觉有些鸡肋,有了if else还造这玩意干啥?不懂

    {{#with}}...{{/with}}

    这个跟{{#each}}...{{/each}}差不多,也是个鸡肋,对比栗子如下:

        <p>with</p>
        {{#with props}}
        <p>Car has {{power}} power and {{speed}} maximum speed</p>
        {{/with}}
    
        <p>each</p>
        {{#each props}}
        <p>Car has {{this}} {{@key}}</p>
        {{/each}}
        
        var context = {
                        props: {
                            power: '150 hp',
                            speed: '200 km/h',
                        }
                    };
        输出:
    with
    Car has 150 hp power and 200 km/h maximum speed
    
    each
    Car has 150 hp power
    Car has 200 km/h speed  

    {{#variableName}}...{{/variableName}}

    If you pass a block expression with helper name that is in the
    expression context, then it will work like {{#each}} helper for this
    context if it is an Array, and will work like {{#with}} helper if it
    is an Object:

    以上是官方的解释,也就是根据传入数据的类型是对象还是数组自动的去执行。

    <p>数组:</p>
        <ul>
            {{#people}}
            <li>{{name}} - {{age}} years old</li>
            {{/people}}
        </ul>
        <p>对象:</p>
        {{#props}}
        <p>Car has {{power}} power and {{speed}} maximum speed</p>
        {{/props}}
        <p>其他</p>
        {{#title}}
        <p>{{this}}</p>
        {{/title}}
        
    people: [
        {
            name: 'John Doe',
            age: 18
        },
        {
            name: 'Mark Johnson',
            age: 21
        }
    ],
    props: {
        power: '150 hp',
        speed: '200 km/h'
    },
    title: 'Friends'
    
    输出:
    数组:
    John Doe - 18 years old
    Mark Johnson - 21 years old
    
    对象:
    Car has 150 hp power and 200 km/h maximum speed
    
    其他
    Friends

    这个方法看起来挺好用,但是我觉得会导致程序读起来不明确,出了错也不容易排查,还是觉得鸡肋。

    {{escape}}

    This plain helper returns escaped HTML string. It escapes only the following characters: < > " &

    这个方法用来把几个特定的字符< > " &转码成HTML字符串,目前我还没想到在什么场景下需要转码。

    <h1>{{title}}</h1>
    <p>{{escape body}}</p>
    
    {
      title: 'Paragraphs',
      body: 'We need to use <p> tags to add paragraphs in HTML',
    }
    
    <h1>Paragraphs</h1>
    <p>We need to use &lt;p&gt; tags to add paragraphs in HTML</p>

    {{js "expression"}}

    js表达式,我觉得这个方法还是比较有用的,之前曾遇到一个问题,通过API后台传过来一堆内容,然后我把它全部填到模板里,但是,这些数据里有些内容,比如文件大小,传过来是字节的,我需要根据大小转成KB,MB,GB等单位,这一步还好,但是计算出来往往小数点后好多位,比如3.222222MB,模板当时用的jquery的,当时就懵逼了,只能去找后端。但是如果模板能够用js表达式的话,这个问题就能解决了。

    <h3>{{title}}</h3>
    <p>Price: ${{js "this.price * 1.2"}} </p>
    <p>{{js "this.inStock ? 'In Stock' : 'Not in stock'"}} </p>
    <p>{{js "this.number.toFixed(2)"}}</p>
    
    title: 'iPhone 6 Plus',
    price: 1000,
    inStock: true,
    number:2.22222
    
    输出:
    iPhone 6 Plus
    Price: $1200
    In Stock
    2.22

    {{#js_compare "expression"}}...{{/js_compare}}

    在我看来还不如if else用的顺手,鸡肋

    <h3>{{title}}</h3>
        <p>Price: ${{price}} </p>
        <p>{{#js_compare "this.color === 'white' && this.memory > 16"}}Not in stock{{else}}In stock{{/js_compare}} </p>
        <p>
            {{#if "this.color === 'white' && this.memory > 16"}}
            Not in stock
            {{else}}
            In stock
            {{/if}}
        </p>
        
    title: 'iPhone 6 Plus',
    price: 1000,
    color: 'white',
    memory: 32
    
    iPhone 6 Plus
    Price: $1000
    Not in stock
    Not in stock

    此外,template7还支持添加、删除自定义helpers,即根据需要扩展自己需要的方法,感觉也没啥卵用

    Template7.registerHelper(name, helper)
    
    Template7.unregisterHelper(name)

    name - string - helper name
    helper - function - helper function to handle passed context

    还有几个不常用的方法,就不在说了,有兴趣自己去官网看一下。
    总的来说,感觉template7里面重复的东西太多,之前有看过jquery-tmpl的源码才不到100行,underscore.js内置的模板好像70行以内。而它500行左右,搞了一堆七七八八的内容,但真正平常用到的只是少部分,如果让我用的话,我可能会去掉里面的一些内容再用,或者直接选用更加精简的模板引擎。
    暂时先写到这里,有时间,再补充一点对源码的认识。

  • 相关阅读:
    Java帮助文档的生成
    Java内部类
    Java中利用标签跳出外层循环break
    【转】你真的了解word-wrap和word-break的区别吗?
    Office/Access 2013 扩展支持xbase/DBF 文件
    调用cmd.exe执行pdf的合并(pdftk.exe)
    input 数字输入控制(含小数)
    iis7.5 发布mvc出错的解决办法
    table中超过长度的列,显示省略号
    本地图片的预览和上传
  • 原文地址:https://www.cnblogs.com/10manongit/p/12632151.html
Copyright © 2011-2022 走看看