zoukankan      html  css  js  c++  java
  • 下一代Jquery模板JsRender

    下一代Jquery模板-----JsRender

     

    JsRedner和JsViews(JsViews是再JsRender基础上的进一步封装)被称为下一代的Jquery模板,官方地址:https://github.com/BorisMoore/jsrender;https://github.com/BorisMoore/jsviews。Juqrey模板是一个javascript引擎(抄的、这个东东太高深了),他最直接的作用就是:1、代码重用,减少代码量;(貌似还更容易编写)2、抛弃繁琐的字符串拼接、提高代码可见性、简化维护。

      为什么需要模板

      总之,我是写过无数这样蛋疼的代码:

    复制代码
    var html = '';
    $.each(data.persons, function (i, item) { html
    += "<tr><td>" + item.FirstName + "</td><td><a href='/Person/Edit/"
            
    + item.PersonID + "'>Edit</a> | <a href='/Person/Details/"
            + item.PersonID + "'>Details</a> | <a href='/Person/Delete/"
            + item.PersonID + "'>Delete</a></td>
    </tr>"; });
    $('#XXX').append(html);
    复制代码

      这样写很明显的坏处就是:这样的代码可见性太低,很难维护。或许你几个月之后再来看你的代码,你要花半个小时甚至更多才能得出代码的展示结构。下面来看个JsRender的例子:

    复制代码
    //Templates
    <script type="text/x-jsrender" id="personListTemplate">
        {{for persons}}
            <tr>
                <td>{{:FirstName}}</td>
                <td>
                    <a href="/Person/Edit/{{:PersonID}}">Edit</a> | 
                    <a href="/Person/Details/{{:PersonID}}">Details</a> | 
                    <a href="/Person/Delete/{{:PersonID}}">Delete</a>
                </td>
            </tr>
        {{/for}}
    </script>
    //Render Data
    var html  = $("#personListTemplate").render(data);
    //Insert into Container
    $("#XXX").append(html);
    复制代码

       代码的结构确实清晰可见了,但是代码越看越多了。首先,这是错觉,因为这里的东东都是严格换行了的。其次,这里省去了item、each等字符复杂字符,貌似更容易编写了。

      JsRender和Jquery Template

      既然JsRender是下一代Jquery模板,那么谁是上一代模板呢?Jquery Template。Jquery Template的特点这里就不废话了,说说JsRedner和Jquery Template的差距:

        1、JsRender渲染非常快,网上说的是“和最快一样快”(当然我也不知道他到底有多快)。对于简单的模板的渲染,JsRender的渲染速度比Js Template可以快20倍。

        2、JsRender对Dom和Jquery不存在任何依赖(注:不依赖并不是说不使用...)。在Jquery Template 必须用$.template(name,'XXX')标记模板,然后渲染。JsRedner不用,他甚至可以直接渲染字符串。

        3、JsRender和Jquery Template相比,JsRender仅仅需要更少的代码,2就是一个例子。

      JsRender三要素和行为

      从上面贴的代码可以看出,JsRender需要三要素:模板(Template)、容器(Container:简单。。。)、数据(Data:数据可以使各种js对象:如数组,object等等)。主要行为为:渲染模板、将渲染结果插入容器(这个太简单了)。说下渲染模板先。。。

      JsRender渲染模板

      1、无需编译直接渲染: 

    var html = $("#XXXXX").render(data); // XXX代表某个脚本标记,也就是上面的<script id="XXX" type="text/x-jsrender">.......</script>

      2、渲染前编译:

    复制代码
    /*A、获取模板对象的方式编译*/
    var xxxTemplate = $.templates("#xxxTemplate");//既可以是字符串也可以是脚本标记,B是字符串
    var html = xxxTemplate.render(data);
    /*B、指定模板名称的方式编译*/
    $.templates('xxx','<b>{{:name}}</b>');
    $.templates({
      'yyy','<b>{{:name}}</b>',
      'zzz','<b>{{:name}}</b>'

    });
    var html = $.render.xxx(data);//注意,第B种方式可以同时渲染多个模板,但是第A种方式不行
    复制代码

       总结一下可以看出:1、无编译直接渲染的方式无法用于字符串的渲染;渲染前编译的方式字符串和脚本标记皆可。2、制定模板名称的方式编译可以同时编译多个模板,但是获取模板对象的方式编译只能编译一个模板。

      JsRender模板(Template)

      基本的jsRender标签:JsRender模板主要由html标记和jsrender标签(像上面的{{:XXX}})组成。所有的Jsrender标签都被两个大括号包裹,中间既可以是参数也可以使表达式(如:{{:#index}}和{{:#index+1}}),下面看一下一些基本的Jsrender标签。

    描述 例子 输出
    参数firstName的值(未被Html编码) {{:firstName}} Madelyn
    参数movie的属性--releaseYear的值(未被html编码) {{:movie.releaseYear}} 1987
    比较(表达式,未被html编码) {{:movie.releaseYear < 2000}} true
    经html编码的值(更加安全,但是要耗点内存) {{>movie.name}} Star Wars: Episode VI: <span style='color:purple;font-style: italic;'>Return of the Jedi</span>
    经html编码的值 {{html:movie.name}} Star Wars: Episode VI: <span style='color:purple;font-style: italic;'>Return of the Jedi</span>

       jsrender数据遍历看过ASP.NET MVC利用PagedList分页(二)PagedList+Ajax+JsRender的童鞋对jsrender的数据遍历相信不会陌生,基本语法如下:

    {{for xxx}}
        <li>{{:property of xxx}}</li>
    {{/for}}

       有时候想获取xxx本身怎么办呢?如下:

    {{for  xxx yyy}}
        <li>{{:#data}}</li>
    {{/for}}

      上面的例子要说明两点:1、for不仅仅可以遍历一组数据,他甚至可以同时遍历两组和多组数据(强大了吧...)。2、上面的#data就表示xxx和yyy本生。试想一下,如何xxx和yyy都表示一个基本元素(字符串、整数等等、任意交叉)的数组,那么这个是不是能很好的完成遍历呢?说道#data,不得不提一下#index,#data和#index都是内置的jsrender关键字。下面在一个例子:

    复制代码
    //Template
    {{for #data}}
            <h3>{{:name}}</h3>
            <ul>
            {{for language}}
                 <li> {{:#parent.parent.data.name}} is learning {{:title}}</li>
            {{/for}}
            </ul>
    {{/for}}
    //Data
     var studnets = [
            {
                "name": "Mingjun Tang",
                "language": [{ "title": "English"},{ "title": "Franch"}]
            },
            {
                "name": "Ming Tang",
                "language": [{ "title": "English"}]
            }
    ];
    复制代码

       遍历时#data充当了students,同时#parent.parent.data.XXX可以用于向上迭代。注意这里的data并不是student中的属性额,因为#parent向上迭代后返回的是一个jsrender对象只有,#parent.data后才会返回数组内容。#parent在jsrender叫路径访问,但是我觉得这里叫向上迭代还要好些。

      jsrender条件

    复制代码
    {{if  fullprice}}
        html markup
    {{else halfprice}}
        html markup
    {{else}}
        html markup
    {{/if}}
    复制代码

       也可以吧他们扯开用,如:{{if fullprice}}html markup{{/if}}和{{if fullprice}}html markup{{else}}html markup{{/if}}。但是这里需要注意两点:

      1、if....else....else表示了if elseif else,这里的else表示了elseif。

      2、{{if  fullprice}}中的fullprice条件表达式表示的是fullprice不为空。其实还可以有更懂的条件表达式可以应用到这里来,如下(注意这里的等于和不等于、、、、):

    表达式 举例 注释
    || {{ :a || b }}
    && {{ :a && b }}
    ! {{ :!a }}
    <= 和>=和 <和 > {{ :a <= b }} 比较
    === 和 !== {{ :a === b }} 等于和不等于

      3、在条件表达式中还可以用一些属性进行比较,如{{if  xxx.length > 50}}等等

      jsrender模板嵌套

        在上面一个例子中,嵌套了两个for循环,试想一下,如果这两个for循环结构非常复杂或其下还要嵌套一个甚至多个for循环的时候,上面所说的jsrender提高了代码的可见性和可维护性就不复存在了。于是jsrender也提供了jsrender模板的嵌套,改写一下上上面的JsRender模板:

    复制代码
    <script type="text/x-jsrender" id="studentTemplate">
        {{for #data}}
            <h3>{{:name}}</h3>
            <ul>
            {{for language tmpl="#studentLanguageTemplate" /}}
            </ul>
        {{/for}}
    </script>
    
    <script type="text/x-jsrender" id="studentLanguageTemplate">
        <li> {{:#parent.parent.data.name}} is learning {{:title}}</li>
    </script>
    //render
    $("#studentList").html($("#studentTemplate").render(studnets));
    复制代码

       这样就可以避免无限的嵌套下去,只需要设置{{for}}的tmpl属性即可。这时,tmpl是一个脚本标记。如果studentLanguageTemplate已经被$.templates()编译,那么也可以这么写:

    复制代码
    <script type="text/x-jsrender" id="studentTemplate">
        {{for #data}}
            <h3>{{:name}}</h3>
            <ul>
            {{for language tmpl="studentLanguageTemplate" /}}
            </ul>
        {{/for}}
    </script>
    
    <script type="text/x-jsrender" id="studentLanguageTemplate">
        <li> {{:#parent.parent.data.name}} is learning {{:title}}</li>
    </script>
    //render
    $.templates("studentLanguageTemplate", "#studentLanguageTemplate");
    $("#studentList").html($("#studentTemplate").render(studnets));
    复制代码

      上面的templ不再“#XXX”指向一个脚本标记,而是"XXX"指向一个已经标记的脚本标记。(哈哈 说起来还真绕口)。

      OK,基础的东东就差不多了。不过除了着了,Jsrender还具备良好的可扩展性。后头在慢慢来看看。。。。。

      补充:

      有些朋友在问jsrender现在是否适合用于项目,看官网介绍:

      Warning: JsRender is close to beta, but not yet officially beta, so there may still be changes to APIs and features in the coming period.

      jsrender虽然接近测试版,但是还不是正式的测试版。所以它的API或一些功能可能还是会有改动。也就是说jsrender的稳定性可能还不是十分确定,所以如果正式的项目还是建议大家使用Jquery Template。

     
     
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    关于模态/非模态对话框不响应菜单的UPDATE_COMMAND_UI消息(对对WM_INITMENUPOPUP消息的处理)
  • 原文地址:https://www.cnblogs.com/suncms/p/2937018.html
Copyright © 2011-2022 走看看