文章出處

嚴格來講不能說是MVC,應為模版里不能寫邏輯語句。

靈感來源于我的上篇文字:《封裝JSON數據轉自定義HTML方法parseHTML》

這里再封裝一個簡單方法,在保持原來的方便改變不大的前提下,簡單地根據數據長度,循環地翻譯模版,再插入指定節點里;

只是覺得我的開發過程中很多時候要拼接字符串,拼接起來的字符串又難維護;

這個方法主要是為了提高以后編碼的效率,開發過程中減少手工拼接字符串的重復勞動。

不是為了MVC而MVC;

來看看QQ網購首頁的部分源碼:

 1 <script type="text/html" id="floorMidCommTpl">
 2 <%for(var i=0,j=arr.length;i<j;i++){%>
 3 <li>
 4     <a href="<%=arr[i].clickUrl%>" title="<%=arr[i].itemFullName%>" class="img_wrap" target="_blank"><img init_src="<%=arr[i].uploadPicUrl1%>" width="120" height="120" alt="<%=arr[i].itemFullName%>"/></a>
 5     <div class="img_detail">
 6         <p class="price_now">&yen;<%=(arr[i].activePrice/100).toFixed(2)%></p>
 7         <p class="name"><a href="<%=arr[i].clickUrl%>" target="_blank"><%=arr[i].itemFullName%></a></p>
 8     </div>
 9 </li>
10 <%}%>
11 </script>

提供了豐富的語法支持,驚嘆不已!!! 

官方說其模版引擎壓縮版才2kb,《高性能JavaScript模板引擎原理解析》

看了全篇文章,只能感嘆作者的厲害,超出我的能力范圍。

以后會繼續反復看,不知道什么時候才能深入得理解!

看看我的方法吧: 

1.模版例子,沒有語法支持,也不打算以后支持。繼續往下看,會對這個問題提供解決方法。

1 <ul id="DemoTarget"></ul>
2 <script type="text/html" id="DemoTpl">
3     <li>姓名:{name}</li>
4     <li>性別:{sex}</li>
5 </script>
<ul id="DemoTarget"></ul>

這里需要加個結果插入節點,之前考慮直接用script.appendBefore()方式插入,

但是考慮在同一個位置可以反復插入數據,同時清除之前的結構,就多加一個條件。

2.數據例子:

var DemoJSON = [{
    name: '蠟筆小新',
    sex: 0
}, {
    name: '小丸子',
    sex: 1
}, {
    name: '凹凸曼',
    sex: -1
}];

 3.調用方式

minTemplate.pro({
    temp: 'DemoTpl',
    target: 'DemoTarget',
    json: DemoJSON,
    filter: function (key, val) {
        //如果是{sex}對應的數值返回相應的文字
        if (key == 'sex') {
            return ['保密', '男', '女'][val + 1];
        }
        return val;
    }
});

filter回調函數,使得數據顯示更加靈活, 一定意義上彌補了模版不支持邏輯的語句的缺點。

4.就這么簡單,返回的結果是:

<ul id="DemoTarget">
    <li>姓名:蠟筆小新</li>
    <li>性別:男</li>

    <li>姓名:小丸子</li>
    <li>性別:女</li>

    <li>姓名:凹凸曼</li>
    <li>性別:保密</li>
</ul>

5.minTempate源碼:

var minTemplate = {
        temp:{},
        target: {},
        flag: false,
        /**
         * JSON數據轉自定義HTML.
         * @param  {String} template 模版參數模版的變量名要與JSON的key值對應,
         *                           且模版的變量名要用"{}"包住。
         * @param  {Object} json     JSON數據,只接收類似[{},{}...]格式的JOSN。
         * @param  {String} result   開頭默認的字符串,也被內部遞歸利用。
         * @param  {Function} fn     回調函數前面兩個參數分別對應json的,key 和 value
         * @return {String}          返回轉義的HTML。
         */
        base: function (template, json, fn, result) {
            result = result || '';
            json = !this.flag ? json.slice(0) : json;//第一次遞歸前,克隆一個json
            this.flag = true;
            if (Object.prototype.toString.call(json) === '[object Array]') {
                var first = json.shift();
                result += template.replace(/\{([^{}]+)\}/g, function (match, key) {
                    return fn === undefined ? first[key] : fn(key, first[key]);
                });
                if(json.length !== 0){
                    return this.base(template, json, fn, result); //遞歸
                }
                this.flag = false;
                return result;
            } else {
                alert('只接收數組形式的JSON數據!');
            }
        },
        /**
         * JSON數據轉自定義HTML.
         * @param  {Object} config 配置具體參數如下:
         * @config {String} temp   模版節點ID 
         * @config {String} traget 插入結果的節點ID
         * @config {Object} json   需要轉換的JSON數據,只接收類似[{},{}...]格式的JOSN。
         * @config {Function} filter 結果篩選,函數前面兩個參數分別對應json的,key 和 value
         */
        pro: function (config) {
            this.temp[config.temp] = this.temp[config.temp] || document.getElementById(config.temp)
            this.target[config.target] = this.target[config.target] || document.getElementById(config.target);
            this.target[config.target].innerHTML = this.base(this.temp[config.temp].innerHTML, config.json, config.filter);
        }
};

 


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()