web前端JS整理之Handlebars介紹

web前端JS整理


引入

對於java web開發,涉及到頁面展示時,比較主流的有兩種解決方案

1. struts2+vo+el表達式。

         這種方式,重點不在於struts2,而是vo和el表達式,其基本思想是:根據頁面需要的信息,構造出一個實體,這個實體中包含了界面需要的所有屬性,通常這個實體是由N個表中的字段構成的,俗稱vo。由於vo的屬性可以是String、List、Map等等等,又可以vo套vo,因此這種方式非常靈活,也非常好用。

         在後臺對vo進行賦值,通過struts2封裝到request中,然後在界面用el表達式,通常是${}、forEach標籤什麼的,即可構造出界面。

         但這種方式小菜卻不是很看好。因爲這種利用標籤控制html,依然是把表現和控制混雜在一起,html裏邊混雜了大量el控制標籤,很不美觀。

         當然,小菜不可能因爲這麼簡單的理由拒絕這種方式,讀者仔細思考可以發現,利用el表達式生成html代碼,這是一個在服務器端執行的動作,在服務器端解析完成之後,才發送到客戶端瀏覽器上,這樣做會佔用大量服務器資源,而且速度緩慢。

示例代碼:

<c:forEach var='bm' items="${contractAuditVo.borrowerModels}">
   <table>
     <tbody>
       <tr>
         <td>借款人編號:</td>
         <td>
           <p>
             ${bm.borrowerId }
           </p>
         </td>
       </tr>
       <tr>
         <td>客戶編號:</td>
         <td>
           <p>
             ${bm.customerId }
           </p>
         </td>
       </tr>
       <tr>
         <td>曾用名:</td>
         <td>
           <p>
             ${bm.usedName }
           </p>
         </td>
       </tr>
     </tbody>
   </table>
 </c:forEach>
2. Json+ajax+拼html。

         這種方法一般是基於ajax請求,要求服務器端返回一個json類型的json字符串,這個json串中包含了界面所需的所有信息,界面拿到json串後,構造出html,完成界面展示。

         小菜推薦這種方法,通過這種方式編寫的頁面,反應速度非常快,用戶體驗非常好。

         因爲服務器端只需要提供一個json串,由客戶端完成解析,因此服務器承受的壓力很小,目前的電腦配置都較高,客戶端的瀏覽器解析js腳本很快,因此頁面體驗效果好。

         解析的過程大致是通過Jquery的each方法,進行遍歷。

         但是小菜利用這種方式時,犯了一個致命的錯誤,小菜是通過原始的拼接html的方式,頁面中寫了大量html+=”<div>”;,這種寫法使頁面變得非常凌亂,幾乎不可以維護。

         示例代碼:

var contractTextHtml="";
 $.each(jsonObject.cl,function(i,n){
   
   contractTextHtml="";
   
   //插入合同文本數據
   contractTextHtml+="<div title='出借人信息---"+hiddenNull(n.cm.lenderName)+"' style='overflow:auto;padding:5px;'>";
   contractTextHtml+="<table class='ui-table ui-table-noborder'>";
   contractTextHtml+="<tbody>";
   contractTextHtml+="<tr><td>合同編號:</td><td><p>"+hiddenNull(n.cm.contractId)+"</p></td></tr>";
   contractTextHtml+="<tr class='ui-table-split'><td>出借人姓名:</td><td><p>"+hiddenNull(n.cm.lenderName)+"</p></td></tr>";
   contractTextHtml+="<tr><td>出借人證件類型:</td><td><p>"+hiddenNull(n.cm.lenderIdType)+"</p></td></tr>";
   contractTextHtml+="<tr class='ui-table-split'><td>出借人證件號:</td><td><p>"+hiddenNull(n.cm.lenderIdNum)+"</p></td></tr>";
   contractTextHtml+="<tr><td>出借金額:</td><td><p>"+hiddenNull(n.cm.lenderAmount)+"</p></td></tr>";
   contractTextHtml+="<tr class='ui-table-split'><td>出借人編號:</td><td><p>"+hiddenNull(n.cm.lenderNo)+"</p></td></tr>";
   contractTextHtml+="<tr><td>出借人銀行帳號:</td><td><p>"+hiddenNull(n.cm.lenderBankAccount)+"</p></td></tr>";
   contractTextHtml+="<tr class='ui-table-split'><td>撮合編號:</td><td><p>"+hiddenNull(n.cm.makeMatchNo)+"</p></td></tr>";
   contractTextHtml+="</tbody>";
   contractTextHtml+="</table>";
   contractTextHtml+="</div>";
   $("#textList").append(contractTextHtml);
 });
造成這種問題的根本原因在於拼接html打亂了html原有的層次結構,看不出來哪裏是哪裏,沒有了層次結構的代碼,堆在那裏就像是一坨垃圾。el表達式構造html優點是能夠保持html原有格式,js構造html優點是速度快省資源,爲什麼我們不能把二者的優點結合在一起呢?這就是Handlebars.js。 既然要在項目中引入js模版引擎,就必須進行技術選型,嚴格考覈之後,纔可以引入,就好像是木桶效應,不能讓他成爲項目中的短板。



Handlebars 是 JavaScript 一個語義模板庫,通過對view和data的分離來快速構建Web模板。它採用"Logic-less template"(無邏輯模版)的思路,在加載時被預編譯,而不是到了客戶端執行到代碼時再去編譯, 這樣可以保證模板加載和運行的速度。Handlebars兼容Mustache,你可以在Handlebars中導入Mustache模板



Handlebars.js是一款基於Jquery的插件,以json對象爲數據源,支持邏輯判斷、循環等操作,同時具有非常好的擴展性,體積60KB左右,經過小菜仔細的分析研究,這是一款不可多得的js模版引擎。

如何使用:引用

<script type="text/javascript" src="script/jquery.js"></script>
<script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>


<!DOCTYPE html>
<html>
  <head>
    <META http-equiv=Content-Type content="text/html; charset=utf-8">
    <title>each-基本循環使用方法 - by 楊元</title>
  </head>
  <body>
    <h1>each-基本循環使用方法</h1>
    <!--基礎html框架-->
    <table>
      <thead>
        <tr>
          <th>姓名</th>
          <th>性別</th>
          <th>年齡</th>
        </tr>
      </thead>
      <tbody id="tableList">
        
      </tbody>
    </table>
    
    <!--插件引用-->
    <script type="text/javascript" src="script/jquery.js"></script>
    <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
    
    <!--Handlebars.js模版-->
    <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操作語句-->
    <!--id可以用來唯一確定一個模版,type是模版固定的寫法-->
    <script id="table-template" type="text/x-handlebars-template">
      {{#each student}}
        <tr>
          <td>{{name}}</td>
          <td>{{sex}}</td>
          <td>{{age}}</td>
        </tr>
      {{/each}}
    </script>
    
    <!--進行數據處理、html構造-->
    <script type="text/javascript">
      $(document).ready(function() {
        //模擬的json對象
        var data = {
                    "student": [
                        {
                            "name": "張三",
                            "sex": "0",
                            "age": 18
                        },
                        {
                            "name": "李四",
                            "sex": "0",
                            "age": 22
                        },
                        {
                            "name": "妞妞",
                            "sex": "1",
                            "age": 18
                        }
                    ]
                };
        
        //註冊一個Handlebars模版,通過id找到某一個模版,獲取模版的html框架
        var myTemplate = Handlebars.compile($("#table-template").html());
        
        //將json對象用剛剛註冊的Handlebars模版封裝,得到最終的html,插入到基礎table中。
        $('#tableList').html(myTemplate(data));
      });
    </script>
  </body>
</html>



<script id="IDX_ASS_INFO" type="text/x-handlebars-template">
<thead>
    <tr style="background-color:#f4fbff">
    <th style="padding-right:8px;padding-left:8px"><input id="th_checkbox" type="checkbox" onclick="Idx_Assemble.checkButtonEvent.allCheck(this);"></th>
    <th>指標名稱</th>
    <th>指標分類</th>
    <th>指標版本</th>
    <th>操作</th>
    </tr>
    </thead>
{{#if this.length}}                                    
    <tbody>    
    {{#each this}}
        <tr>
            {{#if_eq checkFlag compare="1"}}
            <td style="padding-right:8px;padding-left:8px"><input id={{idxId}} value={{versionCodes}} name="childCheckbox" onclick="Idx_Assemble.checkButtonEvent.getChiCheck(this);" checked="true" type="checkbox"></td>
             {{else}}
            <td style="padding-right:8px;padding-left:8px"><input id={{idxId}} value={{versionCodes}} name="childCheckbox" onclick="Idx_Assemble.checkButtonEvent.getChiCheck(this);" type="checkbox"></td>
             {{/if_eq}}
            <td>{{idxName}}</td>
            <td>{{idxFolderPath}}</td>
            <td>
                <div class="select_w120">
                
                <select class="select_w120" id=seloption{{idxId}} style="display: block">
                {{#with versionCodes}}
                {{#each this}}                
                <option>{{this}}</option>
                {{/each}}
                {{/with}}
                </select>

                </div>
             </td>
               <td>
            <button type="button" onclick="Idx_Assemble.checkButtonEvent.deleteOne({{idxId}})" class="button_dashed_blue">刪除</button>
               </td>
       </tr>
    {{/each}}
</tbody>
{{/if}}

</script>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章