ejs v9 javascript模板系统

  本版本就是改回v6的形态,后端数据还是带@前端才方便查看与调试。昨天也与一TX前端工程师讨论过这个必要性。取得模板中的需要填写的变量,再与后端传过来的JSON进行比较,尽早进行数据验证。这种技术,可以看一看PHP的变量命名就知了,带是带$前缀。

  在之前的版本中,如果输出语句带分号或逗号是会报错的

  

复制代码 代码如下:

  <script type="tmpl" id="table_tmpl">

  <table>

  <& for(var i=0,tl = @trs.length,tr;i<tl;i++){ &>

  <& tr = @trs[i]; &>

  <tr>

  <td><&= tr.name; &></td> <td><&= tr.age; &></td> <td><&= tr.sex || "男" &></td>

  </tr>

  <& } &>

  </table>

  <&# 怎么可能不支持图片 &>

  <img src="<&= @href &>">

  </script>

  因为内部生成的字符串是这个样子的:

  __views(data.tr.name;)

  为了防止用户顺手把个逗号或分号上去,本版本自动帮你处理了.

  

复制代码 代码如下:

  rlastSemi = /[,;]\s*$/

  // 略

  case "="://处理后台返回的变量(输出到页面的);

  logic = els[0].substring(1);

  if(logic.indexOf("@")!==-1){

  temp.push( startOfHTML, logic.replace(rAt,"$1data.").replace(rlastSemi,''), endOfHTML );

  }else{

  temp.push( startOfHTML, logic.replace(rlastSemi,''), endOfHTML );

  }

  break;

  例子

  下面是一个模板,放置于浏览器会忽略解析JS代码的script标签之内, 注意trs与href前面都带有@标识符。

  

复制代码 代码如下:

  <script type="tmpl" id="table_tmpl">

  <table>

  <& for(var i=0,tl = @trs.length,tr;i<tl;i++){ &>

  <& tr = @trs[i]; &>

  <tr>

  <td><&= tr.name &></td> <td><&= tr.age &></td> <td><&= tr.sex || "男" &></td>

  <&# 导入子模板 &>

  <&= $.ejs("tds_tmpl"); &>

  </tr>

  <& } &>

  </table>

  <&# 怎么可能不支持图片 &>

  <img src="<&= @href &>">

  </script>

  <!-- 这是子模板 -->

  <script type="tmpl" id="tds_tmpl">

  <td>静态的表格</d> <td>静态的表格</d> <td>静态的表格</d>

  </script>

  这是它的JS代码:

  

复制代码 代码如下:

  $.require("ready,more/ejs,node", function(){

  var trs = [

  {name:"隐形杀手",age:29,sex:"男"},

  {name:"索拉",age:22,sex:"男"},

  {name:"fesyo",age:23,sex:"女"},

  {name:"恋妖壶",age:18,sex:"男"},

  {name:"竜崎",age:25,sex:"男"},

  {name:"你不懂的",age:30,sex:"女"}

  ]

  var html = $.ejs("table_tmpl",{

  trs: trs,

  href: "http://www.glzy8.com//rubylouvre/202906/o_type4.jpg"

  });

  $("#table_tc").html(html)

  });

ejs v9 javascript模板系统

  ejs源代码

  

复制代码 代码如下:

  $.define("ejs", "lang",function(){

  var

  _startOfHTML = "\t__views.push(",

  _endOfHTML = ");\n",

  sRight = "&>",

  rLeft = /\s*<&\s*/,

  rRight = /\s*&>\s*/,

  rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g,

  rLastSemi = /[,;]\s*$/

  var ejs2 = $.ejs = function(id,data){

  data = data || {};

  if( !ejs2[id] ){

  var rleft = rLeft,

  rright = rRight,

  sright = sRight,

  rlastSemi = rLastSemi,

  startOfHTML = _startOfHTML,

  endOfHTML = _endOfHTML, str , logic,

  el = document.getElementById(id);

  if (!el) throw "can not find the target element";

  str = el.innerHTML;

  var arr = str.trim().split(rleft),

  buff = ["var __views = [];\n"],temp = [],i = 0,n = arr.length,els,segment;

  while(i < n){//逐行分析,以防歧义

  segment = arr[i++];

  els = segment.split(rright);

  if( ~segment.indexOf(sright) ){//这里不使用els.length === 2是为了避开IE的split bug

  switch ( els[0].charAt(0) ) {

  case "="://处理后台返回的变量(输出到页面的);

  logic = els[0].substring(1);

  if(logic.indexOf("@")!==-1){

  temp.push( startOfHTML, logic.replace(rAt,"$1data.").replace(rlastSemi,''), endOfHTML );

  }else{

  temp.push( startOfHTML, logic.replace(rlastSemi,''), endOfHTML );

  }

  break;

  case "#"://处理注释

  break;

  default://处理逻辑

  logic = els[0];

  if(logic.indexOf("@")!==-1){

  temp.push( logic.replace(rAt,"$1data."), "\n" );

  }else{

  temp.push( logic, "\n" );

  }

  }

  //处理静态HTML片断

  els[1] && temp.push(startOfHTML, $.quote( els[1] ), endOfHTML)

  }else{

  //处理静态HTML片断

  temp.push(startOfHTML, $.quote( els[0] ), endOfHTML );

  }

  }

  ejs2[id] = new Function("data",buff.concat(temp).join("")+';return __views.join("");');

  return ejs2[id]( data )

  }

  return ejs2[id]( data )

  }

  })

  // ejs v9!