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);
            }
    };
  • 相关阅读:
    windows(64位)下使用curl命令
    ThinkPHP 3.2 性能优化,实现高性能API开发
    如何摆脱恨死人的低价竞争对手
    火狐浏览器如何js关闭窗口的几种解决方法
    当 Swoole 遇上 ThinkPHP5 世界你好
    TCP网络编程杂谈
    SQL语句操作优先级顺序
    记一次常规的Mysql数据库访问的时间分析
    CSS艺术字
    Eclipse Oxygen创建maven web项目(二)
  • 原文地址:https://www.cnblogs.com/fengyuqing/p/javascript_template.html
Copyright © 2011-2022 走看看