用模板引擎Art-Template渲染空格或換行符引起的一場「命案」

1、緒論

說實話,真的不知道如何給這篇博客命名,由於我以爲應該有一些小夥伴遇到跟我一樣的問題正在抓耳撓腮中。javascript

2、導火索

最近在作一個移動H5翻頁的功能,相似於MAKA模板那種。假設大體框架以下html


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

初始代碼以下jquery

<!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模板引擎很容易就能實現。web

<!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說,出於種種緣由你把數據格式改爲下面這樣吧,我才比較好處理接下來的工做。app

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/>不就好了嘛。this

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

可是最後發現仍是我太天真了,不管是<br/>仍是\n甚至是&amp;在模板引擎渲染出來以後都是相似這樣的spa


壓根就是當作字符串了,並且暫時來講我還找不到方法能夠解決這個問題,「命案」由此發生。

3、探尋之路

用新的模板引擎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>  

 

相關文章
相關標籤/搜索