artTemplate 動態加載模版

問題 

  以前項目中一直有用到artDialog對話框組件,做者後期又發佈了js模版引擎,使用過幾回,效果感受還挺好。當本身想把模版放在html以外時,遇到了一點問題。css

  做者介紹的方式,是在js文件中,經過定義變量,拼接模版,示例以下:html

var source =
  '<ul>'
+    '<% for (var i = 0; i < list.length; i ++) { %>'
+        '<li>索引 <%= i + 1 %> :<%= list[i] %></li>'
+    '<% } %>'
+ '</ul>';

var data = {
    list: ['文藝', '博客', '攝影', '電影', '民謠', '旅行', '吉他']
};

var render = template.compile(source);
var html = render(data);
document.getElementById('content').innerHTML = html;

  我的很不喜歡這種方式,雖然做者有數據證實,用加號拼接字符串,在現代瀏覽器中,性能十分強勁,但模版看起來很是不直觀。修改起來很鬱悶,有時候一個逗號錯誤,一上午就過去了。相比之下,我仍是很喜歡在頁面裏配置的這種方式:前端

<script id="test" type="text/html">
<h1><%=title%></h1>
<ul>
    <%for(i = 0; i < list.length; i ++) {%>
        <li>條目內容 <%=i + 1%><%=list[i]%></li>
    <%}%>
</ul>
</script>

  這樣看起來比拼接的舒服一點,並且容易修改。jquery

  問題就來了,能不能二者兼得呢?git

解決方案

  首先在外部定義模版,我採用的是模版提供的簡便語法,但願瞭解更多點擊這裏github

using System;
namespace Model
{
    public class {{name}}
    {
        {{each data}}
        /// <summary>
        /// {{$value.列說明}}
        /// </summary>
        public {{$value.數據類型}} {{$value.列名}} { get; set; }
        {{/each}}
    }
}

  接着,Html底部添加srcipt標記,指向上述模版地址。ajax

<script type="text/html" id="tmModel" src="template/model.txt"></script>

  接下來要處理的則是經過ajax根據路徑獲取到模版內容,而後編譯它,編譯完成後便可使用了。關鍵代碼以下:後端

(function () {
    var tems = document.getElementsByTagName('script');

    for (var i = 0; i < tems.length; i++) {
        var t = tems[i];
        if (!t.id || !t.id.length || !t.src || !t.src.length || 'text/html' != t.type) continue;
        var obj = { src: t.src, id: t.id };
        //清除原來的模板信息
        t.id = "";
        t.src = "";
        ajaxrequest(obj.src, 'get', true, null, function (http, obj) {
            //預編譯模版
            template.compile(obj.id, http.responseText.replace(/^\s*|\s*$/g, ""));
        }, obj);
    }
})();

  其中加載模版時,我採用的是Get方式 同步加載,避免模版未編譯就使用。瀏覽器

  模版在加載完畢後,便可使用。看官方的語法:異步

 var html = template.render('tmTab', { data:[]});//tmTab 是咱們以前定義的Script標籤ID,編譯完成後,便可直接使用該模版

  html則是根據模版+數據編譯後的html代碼了。

  拓展的js代碼以下,不依賴jquery:

/**
 * 獲得ajax對象
 */
function getajaxHttp() {
    var xmlHttp;
    try {
        // Firefox, Opera 8.0+, Safari
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        // Internet Explorer
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                alert("您的瀏覽器不支持AJAX!");
                return false;
            }
        }
    }
    return xmlHttp;
}
/**
 * 發送ajax請求
 * url--url
 * methodtype(post/get)
 * con (true(異步)|false(同步))
 * parameter(參數)
 * functionName(回調方法名,不須要引號,這裏只有成功的時候才調用)
 * (注意:這方法有二個參數,一個就是xmlhttp,一個就是要處理的對象)
 * obj須要到回調方法中處理的對象
 */
function ajaxrequest(url, methodtype, con, parameter, functionName, obj) {
    var xmlhttp = getajaxHttp();
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4) {
            //HTTP響應已經徹底接收才調用
            functionName(xmlhttp, obj);
        }
    };
    xmlhttp.open(methodtype, url, con);
    xmlhttp.send(parameter);
}



(function () {
    var tems = document.getElementsByTagName('script');

    for (var i = 0; i < tems.length; i++) {
        var t = tems[i];
        if (!t.id || !t.id.length || !t.src || !t.src.length || 'text/html' != t.type) continue;
        var obj = { src: t.src, id: t.id };
        //清除原來的模板信息
        t.id = "";
        t.src = "";
        ajaxrequest(obj.src, 'get', true, null, function (http, obj) {
            //預編譯模版
            template.compile(obj.id, http.responseText.replace(/^\s*|\s*$/g, ""));
        }, obj);
    }
})();
templateExtension.js

最後

  相比使用MVC的Razor視圖引擎,我的更傾向於使用js類的前端模版。

  在我看來,用戶最後看到的網頁,無非就是網頁+數據。 網頁呈現這一部分,根據業務類別如何顯示,徹底交給html js css來作,後端無論是語言,提供相應的數據便可。

  固然,過多的ajax可能不利於SEO,不過我一直作的,都是內網用的,可能根本就不須要SEO。

  一點拙見,歡迎你們指正。

相關文章
相關標籤/搜索