AJAX——模板引擎

模板引擎

是爲了使用戶界面與業務數據(內容)分離而產生的,它可以生成特定格式的文檔,用於網站的模板引擎就會生成一個標準的HTML文檔。 

爲什麼要使用模板引擎

我們通過ajax獲取到數據後,需要把數據渲染到頁面,在學習模板引擎前,我們的做法是大量的拼接字符串,對於結構簡單的頁面,這麼做還行

但是如果頁面結構很複雜,使用拼串的話代碼可閱讀性非常的差,而且非常容易出錯,後期代碼維護也是相當的麻煩。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="user">
    <p>姓名: xx</p>
    <p>年齡: xx</p>
    <p>性別: xx</p>
    <p>描述: xx</p>
  </div>
  <script>   
    // 找對象
    var user = document.getElementById("user");

    // 從後臺通過 ajax 獲取數據
    var obj = {
      name: "小王",
      age: 18,
      sex: "男",
      desc: "猥瑣"
    }
    // 字符串拼接
    var htmlStr = " <p>姓名: " + obj.name + "</p> " +
                  " <p>年齡: " + obj.age + "</p> " +
                  " <p>性別: " + obj.sex + "</p> " +
                  " <p>描述: " + obj.desc + "</p> ";
    user.innerHTML = htmlStr;
    // 缺點:
    // 1. html標籤代碼 和 js 代碼混在一起, 代碼冗餘
    // 2. 字符串拼接非常麻煩, 維護起來不方便
  </script> 
</body>
</html>

總結來說拼串渲染兩大缺點:

  1. js中大量充斥着 html 結構拼串代碼, 很冗餘, 可讀性差

  2. 字符串拼接很麻煩, 且維護起來也很麻煩, 容易出錯

常見的模板引擎

BaiduTemplate:http://tangram.baidu.com/BaiduTemplate/

velocity.js:https://github.com/shepherdwind/velocity.js/

ArtTemplate:https://github.com/aui/artTemplate

artTemplate是使用最廣泛,效率最高的模板引擎,需要大家掌握。

artTemplate的使用

github地址(https://github.com/aui/art-template)

中文api地址(https://aui.github.io/art-template/docs/ )

 

artTemplate入門

1.引入模板引擎的js文件

<script src="template-web.js"></script>

2.準備模板

<!--
  指定了type爲text/html後,這一段script標籤並不會解析,也不會顯示。
-->
<script type="text/html" id="myTmp">
  <p>姓名:隔壁老王</p>
  <p>年齡:18</p>
  <p>技能:查水錶</p>
  <p>描述:年輕力氣壯</p>
</script>

3.準備數據

//3. 準備數據,數據是後臺獲取的,可以隨時變化
var json = {
  userName:"隔壁老王",
  age:18,
  skill:"查水錶",
  desc:"年輕氣壯"
}

4.將模板與數據進行綁定

//第一個參數:模板的id
//第二個參數:數據
//返回值:根據模板生成的字符串。
var html = template("myTmp", json);
console.log(html);

5.修改模板

<script type="text/html" id="myTmp">
  <p>姓名:{{userName}}</p>
  <p>年齡:{{age}}</p>
  <p>技能:{{skill}}</p>
  <p>描述:{{desc}}</p>
</script>

6.將數據顯示到頁面

var div = document.querySelector("div");
div.innerHTML = html;

artTemplate標準語法

if語法

{{if gender='男'}}
  <div class="man">
{{else}}
  <div class="woman">
{{/if}}

each語法

<!--
  1. {{each data}}  可以通過$value 和 $index獲取值和下標
  2. {{each data v i}}  自己指定值爲v,下標爲i
-->
{{each data v i}}
<li>
  <a href="{{v.url}}">
    <img src="{{v.src}}" alt="">
    <p>{{v.content}}</p>
   </a>
 </li>
{{/each}}

 注意:

//如果返回的數據是個數組,必須使用對象進行包裹,因爲在{{}}中只寫書寫對象的屬性。
var html = template("navTmp", {data:info});
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    .item {
      float: left;
      width: 320px;
      border: 1px solid #0094ff;
      overflow: hidden;
      margin: 10px;
      padding: 5px;
    }

    .item .title {
      display: block;
      width: 100%;
      position: relative;
    }

    .title img {
      display: block;
      height: 180px;

      width: 100%;
    }

    .title span {
      position: absolute;
      right: 20px;
      bottom: 0px;
      width: 50px;
      text-align: center;
      background-color: lightgray;
      color: gray;
      font-size: 13px;
      border-radius: 5px 5px 0 0;
    }

    .content {
      height: 100px;
      padding: 10px;
      overflow: hidden;
    }

    .content a {
      text-decoration: none;
      color: black;
      font-family: "微軟雅黑";
      font-size: 16px;
    }

    .content p {
      color: gray;
      font-size: 13px;
      font-family: "微軟雅黑";
      margin-bottom: 0;
    }

    .f_l {
      float: left;
    }

    .f_r {
      float: right;
    }

    .clearfix::before,
    .clearfix::after {
      content: '';
      display: block;
      line-height: 0;
      height: 0;
      clear: both;
      visibility: hidden;
    }

    .info {
      line-height: 25px;
    }

    .info img {
      width: 20px;
      height: 20px;
      vertical-align: middle;
      margin-right: 10px;
    }

    .info a {
      color: gray;
      text-decoration: none;
      font-size: 12px;
      height: 20px;
      line-height: 20px;
      margin: 0 10px;
    }
  </style>
</head>

<body>
  <input type="number" id="num">
  <button id="btn">獲取數據</button>

  <div class="items">

  </div>
</body>
<script src="./js/jquery.min.js"></script>
<script src="./js/template-web.js"></script>
<script type="text/html" id="tpl">
  {{ each items v i }}
    <!--div作爲容器-->
    <div class="item clearfix">
      <a href="#" class='title'>
        <img src="{{ v.img }}" alt="" />
        <span>{{ v.time }}</span>
      </a>
      <div class="content">
        <a href="#">{{ v.title }}</a>
        <p>{{ v.novel }}</p>
      </div>
      <div class="info clearfix">
        <a href="#" class='f_l'>
          <img src="{{ v.icon }}" alt="" />{{ v.name }}</a>
        <a href="#" class='f_r'>信息:{{ v.messNum }}</a>
        <a href="#" class='f_r'>❤: {{ v.starNum }}</a>
        <a href="#" class='f_r'>贊:{{ v.goodNum }}</a>
      </div>
    </div>
  {{ /each }}
</script>
<script>
  // 需求: 點擊獲取數據, 根據input框的值, 獲取對應條數的數據, 進行頁面渲染(模板引擎)

  $('#btn').click(function() {
    var num = $('#num').val();  // 獲取input的框的值
    
    // 發送請求, 獲取數據
    $.ajax({
      type: "get",
      url: "smzdm.php",
      data: {
        num: num
      },
      dataType: "json",
      success: function( info ) {
        console.log( info );   
        // 將模板和數據相結合, 渲染頁面 template( 模板id, 數據對象 );
        // info 中有屬性 items 可以用於遍歷
        var htmlStr = template( "tpl", info );
        $('.items').html( htmlStr );

      }
    })

  })

</script>

</html>
//smzdm.php
<?php

    header('content-type:application/json;charset=utf-8');

    // 讀取數據 -> 一共 10 條數據
    $arr = json_decode(file_get_contents('data/smzdm_novels.json'));

    // 總個數
    $totalNum = count($arr);

    // 定義返回的信息
    $message = '數據獲取成功';


    // 獲取輸出的個數
    if( isset( $_GET['num'] ) ){
        $outputNum = $_GET['num'];

        // 判斷是否超過總個數
        if( $outputNum > $totalNum ) {
           $message = 'num 超出最大值,全部返回';
           $outputNum = $totalNum;
        }

        // 如果小於等於0 按 1 處理
        if ( $outputNum <= 0 ) {
           $message = '至少會返回 1 條數據';
           $outputNum = 1;
        }

    }else{
        // 沒傳, 按最大值處理
        $message = 'num 未設置 全部返回';
        $outputNum = $totalNum;
    }

    // 從數組中隨機取出幾個下標
    // 需要注意: 如果取出一個返回一個下標, 取出多個返回的是索引數組形式, 所以需要對取出一個進行處理
    $randomKeyArr = array_rand($arr, $outputNum);
    if ( $outputNum == 1 ) {
		$randomKeyArr = [ "0" => $randomKeyArr ];
	}

    // 定義 新數組, 根據索引從數組中取數據
    $items = [];
    for( $i = 0; $i < count( $randomKeyArr ); $i++ ){
        $items[ $i ] = $arr[ $randomKeyArr[$i] ];
    }

    echo json_encode( array(
        'message'=> $message,
        'items' => $items
    ));

    // 延遲
    sleep(1);
?>

 

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