zoukankan      html  css  js  c++  java
  • 原生JS不到30行,实现类似javascript MVC的功能-minTemplate

    严格来讲不能说是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);
            }
    };
  • 相关阅读:
    使用 libevent 和 libev 提高网络应用性能
    An existing connection was forcibly closed by the remote host
    各种浏览器的兼容css
    vs输出窗口,显示build的时间
    sass
    网站设置404错误页
    List of content management systems
    css footer not displaying at the bottom of the page
    强制刷新css
    sp_executesql invalid object name
  • 原文地址:https://www.cnblogs.com/fengyuqing/p/javascript_template.html
Copyright © 2011-2022 走看看