用模板引擎Art-Template渲染空格或換行符引發的一場“命案”


一、緒論

說實話,真的不知道如何給這篇博客命名,因為我覺得應該有一些小伙伴遇到跟我同樣的問題正在抓耳撓腮中。

二、導火索

最近在做一個移動H5翻頁的功能,類似於MAKA模板那種。假設大致框架如下


第一頁是首頁,第二頁開始就是要動態添加的地方,所以紅框里面的樣式類,是從2開始的,這是第一個伏筆。

初始代碼如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>命案</title>
</head>
<body>
    <div class="sec_1">
        <p>首頁</p>
    </div>
    <div class="sec_2">
        <p>張三</p>
        <p>性別:男;聯系方式:123;地址:廣州;</p>
    </div>
    <div class="sec_3">
        <p>李四</p>
        <p>性別:女;聯系方式:321;地址:深圳;</p>
    </div>
    <div class="sec_4">
        <p>王五</p>
        <p>性別:男;聯系方式:213;地址:佛山;</p>
    </div>
</body>
</html>

這個看起來用Art_Template模板引擎很容易就能實現。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>命案</title>
    <script type="text/javascript" src="template-web.js"></script>
</head>
<body id="content-area">
    
</body>
<script id="tem" type="text/html">
    <div class="sec_1">
        <p>首頁</p>
    </div>
    {{each page value index}}
    <div class="sec_{{index+2}}">
        <p>{{value["name"]}}</p>
        <p>性別:{{value["sex"]}};聯系方式:{{value["tel"]}};地址:{{value["address"]}};</p>
    </div>
    {{/each}}
</script>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript">
    var data={
        page:[{
            name:"張三",
            sex:"",
            tel:"123",
            address:"廣州"
        },{
            name:"李四",
            sex:"",
            tel:"321",
            address:"深圳"
        },{
            name:"王五",
            sex:"",
            tel:"213",
            address:"佛山"
        }]
    }
    var html = template('tem', data);
    $('#content-area').html(html);
</script>
</html>

用模板引擎渲染效果一模一樣。

當我興高采烈地把這段代碼交給后台開發A的時候,A說,出於種種原因你把數據格式改成下面這樣吧,我才比較好處理接下來的工作。

var data={
        page:[["張三","男","123","廣州"],["李四","女","321","深圳"],["王五","男","213","佛山"]]
    }

好吧,反正原理都一樣,修改之后代碼如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>命案</title>
    <script type="text/javascript" src="template-web.js"></script>
</head>
<body id="content-area">
    
</body>
<script id="tem" type="text/html">
    <div class="sec_1">
        <p>首頁</p>
    </div>
    {{each page value index}}
    <div class="sec_{{index+2}}">
        <p>{{value[0]}}</p>
        <p>性別:{{value[1]}};聯系方式:{{value[2]}};地址:{{value[3]}};</p>
    </div>
    {{/each}}
</script>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript">
    var data={
        page:[["張三","","123","廣州"],["李四","","321","深圳"],["王五","","213","佛山"]]
    }
    var html = template('tem', data);
    $('#content-area').html(html);
</script>
</html>

問題來了,現在的需求是,假如地址太長了,需要換行。這還不簡單,在需要換行的地方加入<br/>不就行了嘛。

var data={
        page:[["張三","男","123","廣<br/>州"],["李四","女","321","深圳"],["王五","男","213","佛山"]]
    }

但是最后發現還是我太天真了,無論是<br/>還是\n甚至是&amp;在模板引擎渲染出來之后都是類似這樣的


壓根就是當做字符串了,而且暫時來說我還找不到方法可以解決這個問題,“命案”由此發生。

三、探尋之路

用新的模板引擎Handlebars來解決。上面所示的案例,表達式中的任何html代碼將會被自動忽略,但是有時候我們需要解析html標簽,那么就要用三個花括號{{{ }}}來解決這個問題。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>命案</title>
    <script type="text/javascript" src="handlebars.js"></script>
</head>
<body id="content-area">
</body>
<script id="address-template" type="text/x-handlebars-template">  
    <div class="sec_1">
        <p>首頁</p>
    </div>
    {{#each page}}
    <div class="sec_{{@index+2}}">
        <p>{{@key[0]}}</p>
        <p>性別:{{@key[1]}};聯系方式:{{@key[2]}};地址:{{{@key[3]}}};</p>
    </div>
    {{/each}}
</script>  

<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(function () {  
  // 抓取模板數據  
  var theTemplateScript = $("#address-template").html();  
  // 編譯模板  
  var theTemplate = Handlebars.compile(theTemplateScript);  
  // 定義數據  
  var data={
        page:[["張三","","123","廣<br/>州"],["李四","","321","深圳"],["王五","","213","佛山"]]
    }
  // 把數據傳送到模板  
  var theCompiledHtml = theTemplate(data);  
  // 更新到模板  
  $('#content-area').html(theCompiledHtml);  
});  
</script>

剛運行就出錯了。因為這個模板剛上手,所以其實在官網里面,我找不到有在{{}}符號里面進行運算的寫法


最后發現有Helper這個東西,其實就是類似寫一個過濾器,你想把數據過濾成什么樣子都可以通過編輯這個Helper

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>命案</title>
    <script type="text/javascript" src="handlebars.js"></script>
</head>
<body id="content-area">
</body>
<script id="address-template" type="text/x-handlebars-template">  
    <div class="sec_1">
        <p>首頁</p>
    </div>
    {{#each page}}
    <div class="sec_{{formatnumber @index}}">
        <p>{{@key[0]}}</p>
        <p>性別:{{@key[1]}};聯系方式:{{@key[2]}};地址:{{@key[3]}};</p>
    </div>
    {{/each}}
</script>  

<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(function () {  
  // 抓取模板數據  
  var theTemplateScript = $("#address-template").html();  
  Handlebars.registerHelper('formatnumber', function(num, options){
      num = num + 2;
      return num;
 });
  // 編譯模板  
  var theTemplate = Handlebars.compile(theTemplateScript);  
  // 定義數據  
  var data={
        page:[["張三","","123","廣<br/>州"],["李四","","321","深圳"],["王五","","213","佛山"]]
    }
  // 把數據傳送到模板  
  var theCompiledHtml = theTemplate(data);  
  // 更新到模板  
  $('#content-area').html(theCompiledHtml);  
});  
</script>

Helper的位置必須在編譯模板之前,否則是無效的!!

使用Helper之后,現在又報其他的錯誤


居然連數組的寫法都不支持,但是獲取屬性的寫法卻可以,比如@key["name"]。不得不吐槽這個模板引擎用起來真不方便。

但是最后還是找到解決的思路

<script id="address-template" type="text/x-handlebars-template">  
    <div class="sec_1">
        <p>首頁</p>
    </div>
    {{#each page}}
    <div class="sec_{{formatnumber @index}}">
        <p>{{#with @key}}{{0}}{{/with}}</p>
        <p>性別:{{#with @key}}{{1}}{{/with}};聯系方式:{{#with @key}}{{2}}{{/with}};地址:{{#with @key}}{{{3}}}{{/with}};</p>
    </div>
    {{/each}}
</script>  

很遺憾,用@key雖然沒有出錯了,但是卻渲染不出來。


其實已經離成功很接近了,把@key改成this就可以了

<script id="address-template" type="text/x-handlebars-template">  
    <div class="sec_1">
        <p>首頁</p>
    </div>
    {{#each page}}
    <div class="sec_{{formatnumber @index}}">
        <p>{{#with this}}{{0}}{{/with}}</p>
        <p>性別:{{#with this}}{{1}}{{/with}};聯系方式:{{#with this}}{{2}}{{/with}};地址:{{#with this}}{{{3}}}{{/with}};</p>
    </div>
    {{/each}}
</script>  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM