严格来讲不能说是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">¥<%=(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); } };