Template.js

template.js 一款 JavaScript 模板引擎,简单,好用。提供一套模板语法,用户可以写一个模板区块,每次根据传入的数据,生成对应数据产生的HTML片段,渲染不同的效果。https://github.com/aui/artTemplate

1、特性

(1)、性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍(性能测试)

(2)、支持运行时调试,可精确定位异常模板所在语句(演示)

(3)、对 NodeJS Express 友好支持

(4)、安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板)

(5)、支持include语句

(6)、可在浏览器端实现按路径加载模板(详情)

(7)、支持预编译,可将模板转换成为非常精简的 js 文件

(8)、模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选

(9)、支持所有流行的浏览器

2、语法

(1)、使用

引用简洁语法的引擎版本,例如: <script src="dist/template.js"></script> 

(2)、表达式

{{ 与 }} 符号包裹起来的语句则为模板的逻辑表达式。

(3)、输出表达式

对内容编码输出: {{content}} 
不编码输出: {{#content}} 
编码可以防止数据中含有 HTML 字符串,避免引起 XSS 攻击。

(4)、条件表达式

{{if admin}} 
 <p>admin</p> 
{{else if code > 0}} 
 <p>master</p> 
{{else}} 
 <p>error!</p> 
{{/if}} 

(5)、遍历表达式

      无论数组或者对象都可以用 each 进行遍历。

{{each list as value index}} 
 <li>{{index}} - {{value.user}}</li> 
{{/each}} 

亦可以被简写:

{{each list}} 
 <li>{{$index}} - {{$value.user}}</li> 
{{/each}} 

(6)、模板包含表达式

用于嵌入子模板。

{{include 'template_name'}} 

子模板默认共享当前数据,亦可以指定数据:{{include 'template_name' news_list}} 

(7)、辅助方法

使用template.helper(name, callback)注册公用辅助方法:

template.helper('dateFormat', function (date, format) { 
 // .. 
 return value; 
}); 

模板中使用的方式: {{time | dateFormat:'yyyy-MM-dd hh:mm:ss'}} 
支持传入参数与嵌套使用: {{time | say:'cd' | ubb | link}} 

3、实例

<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>basic-demo</title> 
<script src="../dist/template.js"></script> 
</head> 
<body> 
<div id="content"></div> 
<script id="test" type="text/html"> 
{{if isAdmin}} 
<h1>{{title}}</h1> 
<ul> 
 {{each list as value i}} 
  <li>索引 {{i + 1}} :{{value}}</li> 
 {{/each}} 
</ul> 
{{/if}} 
</script> 
<script> 
var data = { 
 title: '基本例子', 
 isAdmin: true, 
 list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他'] 
}; 
var html = template('test', data); 
document.getElementById('content').innerHTML = html; 
</script> 
</body> 
</html>

<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>no escape-demo</title> 
<script src="../dist/template.js"></script> 
</head> 
  
<body> 
 <h1>不转义HTML</h1> 
 <div id="content"></div> 
 <script id="test" type="text/html"> 
 <p>不转义:{{#value}}</p> 
 <p>默认转义: {{value}}</p> 
 </script> 
  
 <script> 
 var data = { 
  value: '<span style="color:#F00">hello world!</span>' 
 }; 
 var html = template('test', data); 
 document.getElementById('content').innerHTML = html; 
 </script> 
</body> 
</html> 

<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>include-demo</title> 
<script src="../dist/template.js"></script> 
</head> 
  
<body> 
<div id="content"></div> 
<script id="test" type="text/html"> 
<h1>{{title}}</h1> 
{{include 'list'}} 
</script> 
<script id="list" type="text/html"> 
<ul> 
 {{each list as value i}} 
  <li>索引 {{i + 1}} :{{value}}</li> 
 {{/each}} 
</ul> 
</script> 
  
<script> 
var data = { 
 title: '嵌入子模板', 
 list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他'] 
}; 
var html = template('test', data); 
document.getElementById('content').innerHTML = html; 
</script> 
</body> 
</html> 

<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>helper-demo</title> 
<script src="../dist/template.js"></script> 
</head> 
  
<body> 
<h1>辅助方法</h1> 
<div id="content"></div> 
<script id="test" type="text/html"> 
{{time | dateFormat:'yyyy年 MM月 dd日 hh:mm:ss'}} 
</script> 
  
<script> 
/** 
 * 对日期进行格式化, 
 * @param date 要格式化的日期 
 * @param format 进行格式化的模式字符串 
 *  支持的模式字母有: 
 *  y:年, 
 *  M:年中的月份(1-12), 
 *  d:月份中的天(1-31), 
 *  h:小时(0-23), 
 *  m:分(0-59), 
 *  s:秒(0-59), 
 *  S:毫秒(0-999), 
 *  q:季度(1-4) 
 * @return String 
 * @author yanis.wang 
 * @see http://yaniswang.com/frontend/2013/02/16/dateformat-performance/ 
 */ 
template.helper('dateFormat', function (date, format) { 
  
 if (typeof date === "string") { 
  var mts = date.match(/(\/Date(\d+)\/)/); 
  if (mts && mts.length >= 3) { 
   date = parseInt(mts[2]); 
  } 
 } 
 date = new Date(date); 
 if (!date || date.toUTCString() == "Invalid Date") { 
  return ""; 
 } 
  
 var map = { 
  "M": date.getMonth() + 1, //月份 
  "d": date.getDate(), //日 
  "h": date.getHours(), //小时 
  "m": date.getMinutes(), //分 
  "s": date.getSeconds(), //秒 
  "q": Math.floor((date.getMonth() + 3) / 3), //季度 
  "S": date.getMilliseconds() //毫秒 
 }; 
   
  
 format = format.replace(/([yMdhmsqS])+/g, function(all, t){ 
  var v = map[t]; 
  if(v !== undefined){ 
   if(all.length > 1){ 
    v = '0' + v; 
    v = v.substr(v.length-2); 
   } 
   return v; 
  } 
  else if(t === 'y'){ 
   return (date.getFullYear() + '').substr(4 - all.length); 
  } 
  return all; 
 }); 
 return format; 
}); 
  
// -------- 
  
var data = { 
 time: 1408536771253, 
}; 
var html = template('test', data); 
document.getElementById('content').innerHTML = html; 
</script> 
</body> 
</html> 

<div class="row">
        {{each data item}}
        <div class="col-md-3 col-sm-4">
            <div class="card card-reset">
                <div class="card-header">
                    <h3 class="card-title">{{item.examination.examName}}</h3>
                    <p class="examId">(考试ID:{{item.examination.examCode}})</p>
                    <p class="exam-card-classes-count">
                     	 <!--  
						 {{if item.examWl==0}}全科{{/if}} {{if item.examWl==1}}语文{{/if}} {{if item.examWl==2}}数学{{/if}} {{if item.examWl==3}}英语{{/if}} {{if item.examWl==4}}物理{{/if}} {{if item.examWl==5}}化学{{/if}} {{if item.examWl==6}}历史{{/if}} {{if item.examWl==7}}地理{{/if}} {{if item.examWl==8}}政治{{/if}} {{if item.examWl==9}}生物{{/if}}
						-->
                        <i class="icon-group"></i>{{item.examination.grade.name}}  {{item.examination.examDate | dateFormat 'yyyy-MM-dd'}}</p>
                </div>
                <div class="card-body">
                    {{include 'examUploadListTemplate' item}}
                </div>
                <div class="card-footer" data-id="{{item.examination.examCode}}" data-grade-nane="{{item.examination.grade.name}}">
					<!-- 
                    <a onclick="SCHOOL.onClickSchsScore(this)"><i class="iconfont icon-tuichu mb-1"></i> 总分</a>
					-->
                    <a onclick="SCHOOL.onClickSchsDetails(this)"><i class="iconfont icon-tuichu mb-1"></i> 分数</a>
                    <a onclick="SCHOOL.onClickSchsSelect(this)"><i class="iconfont icon-tuichu mb-1"></i> 客观题</a>
 					<a onclick="SCHOOL.onClickSchsAnswer(this)"><i class="iconfont icon-tuichu mb-1"></i> 调分</a>
                    <a onclick="SCHOOL.onClickSchsAnalysis(this)"><i class="iconfont icon-xueshengduantongji mb-1"></i> 分析</a>
                    <a onclick="SCHOOL.onClickSchsClear(this)"><i class="iconfont icon-shanchu mb-1"></i> 清空</a>
                </div>
            </div>
        </div>
        {{/each}}
</div>
    </script>
<script type="text/plain" id="examUploadListTemplate">
        <ul class="anly-xk">
             {{each examinationStatus item}}
				
				{{if item.analyzeStatus == 1}}<img class="is-anly" src="../assets/img/pass.png"> {{/if}}
            {{if examinationStatus.length < 3}} <li class="li-lg" title="{{item.paper.paperName}}">
				<svg width="100%" height="100%" viewBox="0 0 200 200">
                <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.detailScoreStatus == 1}} stroke="#FF3852" {{else}} stroke="#ccc" {{/if}} {{if item.paper.itemStatus == true}} fill="#428BCA" {{else}} fill="#fff" {{/if}} ></circle>
                <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.totalScoreStatus == 1}} stroke="#60CF66" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="310"></circle>
                <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.answerStatus == 1}} stroke="#F79B04" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="160 400"></circle>
                <text x="50%" y="50%" dy=".3em" {{if item.paper.itemStatus == true}} fill="#fff" {{else}} fill="#000" {{/if}}  font-size="50">{{item.paper.subject.name}}</text>
            </svg></li>
            {{else}}<li title="{{item.paper.paperName}}"><svg width="100%" height="100%" viewBox="0 0 200 200">
                <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.detailScoreStatus == 1}} stroke="#FF3852" {{else}} stroke="#ccc" {{/if}} {{if item.paper.itemStatus == true}} fill="#428BCA" {{else}} fill="#fff" {{/if}} ></circle>
                <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.totalScoreStatus == 1}} stroke="#60CF66" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="310"></circle>
                <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.answerStatus == 1}} stroke="#F79B04" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="160 400"></circle>
                <text x="50%" y="50%" dy=".3em" {{if item.paper.itemStatus == true}} fill="#fff" {{else}} fill="#000" {{/if}}  font-size="50">{{item.paper.subject.name}}</text>
            </svg></li>{{/if}}
        {{/each}}
        </ul>
    </script>
    <!-- 导入 -->
	<script type="text/plain" id="schImportDataTemplaet">
        <div class="form-group">
            <select class="form-control form-control-sm" id="subject">
                {{each examinationStatus item}}
                <option value="{{item.paper.paperCode}}">{{item.paper.subject.name}}  {{item.paper.paperName}}</option>
                {{/each}}
            </select>
        </div>
        <div class="form-files">
            <div id="error_info"></div>
            <input type="file" id="import_excel" name="file" class="dropify-fr" data-default-file="" multiple="multiple" accept="application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
        </div>
    </script>
    <!-- 考试分析 -->
	<script type="text/plain" id="schAnalysisTemplate">
        <p class="mb-3">请选择您要进行考试分析的学科</p>
        <div class="form-group text-left" id="schAnySubject">
			<div class="form-check mb-2">
                <input class="form-check-input" type="checkbox" id="schAllAny" style="top: -5px;">
                <label class="form-check-label" for="schAllAny">全选</label>          
			</div>
            {{each examinationStatus item}}
            <div class="form-check mb-1">
                <input class="form-check-input" type="checkbox" name="subjects" id="subjectChickbox{{item.paper.paperCode}}" value="{{item.paper.paperCode}}" style="top: -5px;">
                <label class="form-check-label" for="subjectChickbox{{item.paper.paperCode}}">{{item.paper.subject.name}}</label>
				<p class="float-right">{{item.paper.paperName}}</p>            
			</div>
            {{/each}}
        </div>
    </script>
    <!-- 清空 -->
    <script type="text/plain" id="schClearTemplaet">
		<div class="form-group" id = "clearZT">
			<div class="form-check form-check-inline">
                <input class="form-check-input" type="checkbox" name="ZT" value="1" id="schClear1">
                <label class="form-check-label" for="schClear1">清空导入数据</label>          
			</div>
			<div class="form-check form-check-inline">
                <input class="form-check-input" type="checkbox" name="ZT" value="2" id="schClear2">
                <label class="form-check-label" for="schClear2">清空分析结果</label>          
			</div>
		</div>
		<hr>
		<div class="form-group" id="schClearSubject">
			<div class="form-check mb-2">
                <input class="form-check-input" type="checkbox" id="schAllClear" style="top: -5px;">
                <label class="form-check-label" for="schAllClear">全选</label>          
			</div>
            {{each examinationStatus item}}
            <div class="form-check mb-1">
                <input class="form-check-input" type="checkbox" name="subjects" id="subjectChickbox{{item.paper.paperCode}}" value="{{item.paper.paperCode}}" style="top: -5px;">
                <label class="form-check-label" for="subjectChickbox{{item.paper.paperCode}}">{{item.paper.subject.name}}</label>
				<p class="float-right">{{item.paper.paperName}}</p>            
			</div>
            {{/each}}
        </div>
    </script>
	initSchsSelect : function(srtId, isChecked) {
		let id = parseInt(srtId);
		let schsArr = SCHOOL.getSchsArr();
		let subjectObj = {},
			subjectArr = [];
		for (let i = 0; i < schsArr.length; i++) {
			if (id == schsArr[i].examination.examCode) {
				subjectArr = schsArr[i].examinationStatus;
			}
		};
		subjectObj.examinationStatus = subjectArr;
		if (isChecked) {
			document.getElementById('schAnalysisHtml').innerHTML = template('schAnalysisTemplate', subjectObj);
		} else {
			document.getElementById('schImportDataHtml').innerHTML = template('schImportDataTemplaet', subjectObj);
			Men.dropify();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_24192465/article/details/82587227