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

在ASP.NET MVC利用PagedList分頁(二)PagedList+Ajax+JsRender中提到了JsRender。JsRedner和JsViews(JsViews是再JsRender基礎上的進一步封裝)被稱爲下一代的Jquery模板,官方地址:https://github.com/BorisMoore/jsrender;https://github.com/BorisMoore/jsviews。Juqrey模板是一個javascript引擎(抄的、這個東東過高深了),他最直接的做用就是:一、代碼重用,減小代碼量;(貌似還更容易編寫)二、拋棄繁瑣的字符串拼接、提升代碼可見性、簡化維護。

  爲何須要模板

  總之,我是寫過無數這樣蛋疼的代碼:
複製代碼

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);

複製代碼

  若是以爲這樣仍是不明顯,能夠參見ASP.NET MVC利用PagedList分頁(二)PagedList+Ajax+JsRender中的第四部分,這樣寫很明顯的壞處就是:這樣的代碼可見性過低,很難維護。或許你幾個月以後再來看你的代碼,你要花半個小時甚至更多才能得出代碼的展現結構。下面來看個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的差距:

    一、JsRender渲染很是快,網上說的是「和最快同樣快」(固然我也不知道他到底有多快)。對於簡單的模板的渲染,JsRender的渲染速度比Js Template能夠快20倍。

    二、JsRender對Dom和Jquery不存在任何依賴(注:不依賴並非說不使用...)。在Jquery Template 必須用$.template(name,'XXX')標記模板,而後渲染。JsRedner不用,他甚至能夠直接渲染字符串。

    三、JsRender和Jquery Template相比,JsRender僅僅須要更少的代碼,2就是一個例子。

  JsRender三要素和行爲

  從上面貼的代碼能夠看出,JsRender須要三要素:模板(Template)、容器(Container:簡單。。。)、數據(Data:數據可使各類js對象:如數組,object等等)。主要行爲爲:渲染模板、將渲染結果插入容器(這個太簡單了)。說下渲染模板先。。。

  JsRender渲染模板

  一、無需編譯直接渲染: 

var html = $("#XXXXX").render(data); // XXX表明某個腳本標記,也就是上面的<script id="XXX" type="text/x-jsrender">.......</script>

  二、渲染前編譯:
複製代碼

/*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種方式不行

複製代碼

   總結一下能夠看出:一、無編譯直接渲染的方式沒法用於字符串的渲染;渲染前編譯的方式字符串和腳本標記皆可。二、制定模板名稱的方式編譯能夠同時編譯多個模板,可是獲取模板對象的方式編譯只能編譯一個模板。

  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}}

  上面的例子要說明兩點:一、for不只僅能夠遍歷一組數據,他甚至能夠同時遍歷兩組和多組數據(強大了吧...)。二、上面的#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}}。可是這裏須要注意兩點:

  一、if....else....else表示了if elseif else,這裏的else表示了elseif。

  二、{{if  fullprice}}中的fullprice條件表達式表示的是fullprice不爲空。其實還能夠有更懂的條件表達式能夠應用到這裏來,以下(注意這裏的等於和不等於、、、、):
表達式     舉例     註釋
||     {{ :a || b }}     或
&&     {{ :a && b }}     且
!     {{ :!a }}     非
<= 和>=和 <和 >     {{ :a <= b }}     比較
=== 和 !==     {{ :a === b }}     等於和不等於

  三、在條件表達式中還能夠用一些屬性進行比較,如{{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。javascript

相關文章
相關標籤/搜索