现在的位置: 首页 > 综合 > 正文

Javascript模板模式

2017年08月21日 ⁄ 综合 ⁄ 共 2625字 ⁄ 字号 评论关闭

问题提出:

var template = "<p>Hello, my name is {name}. my father {age} years old.</p>";  
      	var json = { name: "Krasimir",age:50 };

替换为:

<p>Hello, my name is Krasimir. my father 50 years old.</p> 


可以这样实现:

        var template = "<p>Hello, my name is {name}. my father {age.father} years old.</p>";  
      	var json = { name: "Krasimir",age: 29 };
      	var  tempo =  function(str){
           str = str.replace(/([\'|\\])/gm,"\\$1")   //转义掉 \ 和 '
                    .replace(new RegExp('{([^{}]*)}','gim'), "'+(data.$1==null?'':data.$1)+'")  //转化为包括变量的字符串
                    .replace(/[\n\r]/gm,'\\n');    //去除回车换行//
           str = ["return '", str ,"';"].join('');
           return new Function('data',str);
     };
          console.log((tempo(template))(json));

PS:

1、

 var multFun = new Function("x", "y", "return x * y")//这段话其实等效于  function multFun(x, y){  return x*y } 

2、其实该函数就是将原来的字符串str转换为:

return '<p>Hello, my name is '+(data.name==null?'':data.name)+'. my father '+(data.age.father==null?'':data.age.father)+' years old.</p>';

再使用new Function(data, str)转换为参数为data的函数

3、从实现可以看出,对于情况诸如下面,使用tempo()也是可以解决

   var json = { name: "Krasimir",age: { son:29, father:50 } }; 
   var template = "<p>Hello, my name is {name}. I\'m {age.father} years old.</p>";

但是如果包含数组怎么办呢?如果仅仅只是诸如如下的情况,很容易办,依次调用tempo函数即可

 var json = [{ name: "Krasimir",age: 23 }, { name: "Tom",age: 33 }];

tempo.prototype.replaceArray = function(str, arr){
	      var rtn = [];
          for(var i=0,len=arr.length; i<len; i++){
          	 var json = arr[i];
             rtn[i] = (tempo(str))(json);
          }
          return rtn;
    };

但是这还是没有做出任何本质的改变,如果情况如下,其中包含了js语句那这怎么办呢?PS:为了使得能够使用循环,我区别符{}替换为了 <% %>

  var json = { name: "Krasimir",age: [ 23, 74, 56, 78  ]}; 
  var template = "<p>Hello, my name is ,<% this.name %>. my sons ages: <% for(var index in this.age )  { %> : <% this.age[index] years old }   %>  .</p>";

那怎么办?我们需要什么样的字符串来构造函数呢?我想应该如下:

var r=[];
r.push("<p>Hello, my name is ,");
r.push( this.name );
r.push(". my sons ages: ");
 for(var i=0,len= this.age.length; i<len; i++ ) { 
r.push(" ");
r.push( this.age[i]  );
r.push("  ");
  } 
r.push("  years old .</p>");
return r.join(""); 

这样的我只要运行一下这个脚本不就搞定了吗,具体实现如下:

  var json2 = { name: "Krasimir",age: [ 23, 74, 56, 78  ]};
  var template2 = "<p>Hello, my name is ,<% this.name %>. my sons ages: <% for(var i=0,len= this.age.length; i<len; i++ ) { %> <% this.age[i]  %>  <%  } %>  years old .</p>"
     
      var  tempo2 =  function(str){
         	var re = /<%([^%>]+)?%>/g, 
         	    reExp =  /(if|for|else|switch|case|break|{|})(.*)?/g, 
         	    code = 'var r=[];\n', 
         	    cursor = 0;
            var add = function(line, js) {
                 js? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
                        (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
                 return add;
            }
       while(match = re.exec(str)) {
           add(str.slice(cursor, match.index))(match[1], true);
           cursor = match.index + match[0].length;
       }
       add(str.substr(cursor, str.length - cursor));
       code += 'return r.join("");';
       console.log(code)
       return new Function(code.replace(/[\r\t\n]/g, ''));
     };
 
   console.log((tempo2(template2)).apply(json2))

 PS1Apply 方法作用更改this关键字的值,不然this
== tempo2

         2、判断代码段是否属于脚本,这个正则表达式的写法决定了你调用的时候该如何调用

参考文章:http://www.gbtags.com/gb/share/2587.htm

抱歉!评论已关闭.