问题 

  之前项目中一直有用到artDialog对话框组件,作者后期又发布了js模版引擎,使用过几次,效果感觉还挺好。当自己想把模版放在html之外时,遇到了一点问题。

  作者介绍的方式,是在js文件中,通过定义变量,拼接模版,示例如下:

  1. var source =
  2. '<ul>'
  3. + '<% for (var i = 0; i < list.length; i ++) { %>'
  4. + '<li>索引 <%= i + 1 %> :<%= list[i] %></li>'
  5. + '<% } %>'
  6. + '</ul>';
  7.  
  8. var data = {
  9. list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
  10. };
  11.  
  12. var render = template.compile(source);
  13. var html = render(data);
  14. document.getElementById('content').innerHTML = html;

  个人很不喜欢这种方式,虽然作者有数据证明,用加号拼接字符串,在现代浏览器中,性能十分强劲,但模版看起来非常不直观。修改起来很郁闷,有时候一个逗号错误,一上午就过去了。相比之下,我还是很喜欢在页面里配置的这种方式:

  1. <script id="test" type="text/html">
  2. <h1><%=title%></h1>
  3. <ul>
  4. <%for(i = 0; i < list.length; i ++) {%>
  5. <li>条目内容 <%=i + 1%> :<%=list[i]%></li>
  6. <%}%>
  7. </ul>
  8. </script>

  这样看起来比拼接的舒服一点,而且容易修改。

  问题就来了,能不能两者兼得呢?

解决方案

  首先在外部定义模版,我采用的是模版提供的简便语法,希望了解更多点击这里

  1. using System;
  2. namespace Model
  3. {
  4. public class {{name}}
  5. {
  6. {{each data}}
  7. /// <summary>
  8. /// {{$value.列说明}}
  9. /// </summary>
  10. public {{$value.数据类型}} {{$value.列名}} { get; set; }
  11. {{/each}}
  12. }
  13. }

  接着,Html底部添加srcipt标记,指向上述模版地址。

  1. <script type="text/html" id="tmModel" src="template/model.txt"></script>

  接下来要处理的则是通过ajax根据路径获取到模版内容,然后编译它,编译完成后即可使用了。关键代码如下:

  1. (function () {
  2. var tems = document.getElementsByTagName('script');
  3.  
  4. for (var i = 0; i < tems.length; i++) {
  5. var t = tems[i];
  6. if (!t.id || !t.id.length || !t.src || !t.src.length || 'text/html' != t.type) continue;
  7. var obj = { src: t.src, id: t.id };
  8. //清除原来的模板信息
  9. t.id = "";
  10. t.src = "";
  11. ajaxrequest(obj.src, 'get', true, null, function (http, obj) {
  12. //预编译模版
  13. template.compile(obj.id, http.responseText.replace(/^\s*|\s*$/g, ""));
  14. }, obj);
  15. }
  16. })();

  其中加载模版时,我采用的是Get方式 同步加载,避免模版未编译就使用。

  模版在加载完毕后,即可使用。看官方的语法:

  1. var html = template.render('tmTab', { data:[]});//tmTab 是我们之前定义的Script标签ID,编译完成后,即可直接使用该模版

  html则是根据模版+数据编译后的html代码了。

  拓展的js代码如下,不依赖jquery:

  1. /**
  2. * 得到ajax对象
  3. */
  4. function getajaxHttp() {
  5. var xmlHttp;
  6. try {
  7. // Firefox, Opera 8.0+, Safari
  8. xmlHttp = new XMLHttpRequest();
  9. } catch (e) {
  10. // Internet Explorer
  11. try {
  12. xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
  13. } catch (e) {
  14. try {
  15. xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  16. } catch (e) {
  17. alert("您的浏览器不支持AJAX!");
  18. return false;
  19. }
  20. }
  21. }
  22. return xmlHttp;
  23. }
  24. /**
  25. * 发送ajax请求
  26. * url--url
  27. * methodtype(post/get)
  28. * con (true(异步)|false(同步))
  29. * parameter(参数)
  30. * functionName(回调方法名,不需要引号,这里只有成功的时候才调用)
  31. * (注意:这方法有二个参数,一个就是xmlhttp,一个就是要处理的对象)
  32. * obj需要到回调方法中处理的对象
  33. */
  34. function ajaxrequest(url, methodtype, con, parameter, functionName, obj) {
  35. var xmlhttp = getajaxHttp();
  36. xmlhttp.onreadystatechange = function () {
  37. if (xmlhttp.readyState == 4) {
  38. //HTTP响应已经完全接收才调用
  39. functionName(xmlhttp, obj);
  40. }
  41. };
  42. xmlhttp.open(methodtype, url, con);
  43. xmlhttp.send(parameter);
  44. }
  45.  
  46. (function () {
  47. var tems = document.getElementsByTagName('script');
  48.  
  49. for (var i = 0; i < tems.length; i++) {
  50. var t = tems[i];
  51. if (!t.id || !t.id.length || !t.src || !t.src.length || 'text/html' != t.type) continue;
  52. var obj = { src: t.src, id: t.id };
  53. //清除原来的模板信息
  54. t.id = "";
  55. t.src = "";
  56. ajaxrequest(obj.src, 'get', true, null, function (http, obj) {
  57. //预编译模版
  58. template.compile(obj.id, http.responseText.replace(/^\s*|\s*$/g, ""));
  59. }, obj);
  60. }
  61. })();

templateExtension.js

最后

  相比使用MVC的Razor视图引擎,个人更倾向于使用js类的前端模版。

  在我看来,用户最后看到的网页,无非就是网页+数据。 网页呈现这一部分,根据业务类别如何显示,完全交给html js css来做,后端不管是语言,提供相应的数据即可。

  当然,过多的ajax可能不利于SEO,不过我一直做的,都是内网用的,可能根本就不需要SEO。

  一点拙见,欢迎大家指正。

artTemplate 动态加载模版的更多相关文章

  1. [UE4]C++实现动态加载的问题:LoadClass<T>()和LoadObject<T>() 及 静态加载问题:ConstructorHelpers::FClassFinder()和FObjectFinder()

    转自:http://aigo.iteye.com/blog/2281558 动态加载UObject和动态加载UClass分别用LoadObject<T>(),和LoadClass<T ...

  2. [UE4]C++实现动态加载的问题:LoadClass()和LoadObject()

    http://aigo.iteye.com/blog/2281558 原文作者:@玄冬Wong 相关内容:C++静态加载问题:ConstructorHelpers::FClassFinder()和FO ...

  3. js动态加载css和js

    之前写了一个工具类点此链接里面含有这段代码,感觉用处挺多,特意提出来 var loadUtil = { /* * 方法说明:[动态加载js文件css文件] * 使用方法:loadUtil.loadjs ...

  4. geotrellis使用(二十三)动态加载时间序列数据

    目录 前言 实现方法 总结 一.前言        今天要介绍的绝对是华丽的干货.比如我们从互联网上下载到了一系列(每天或者月平均等)的MODIS数据,我们怎么能够对比同一区域不同时间的数据情况,采用 ...

  5. Ext JS 如何动态加载JavaScript创建窗体

    JavaScript不需要编译即可运行,这让JavaScript构建的应用程序可以变得很灵活.我们可以根据需要动态从服务器加载JavaScript脚本来创建和控制UI来与用户交互.下面结合Ext JS ...

  6. Ext动态加载Toolbar

    在使用Ext的GridPanel时候,有时候需要面板不用重新加载而去更新Store或者Toolbar,Store的方法有很多,例如官方api给我们提供的Store.load(),Store.reLoa ...

  7. Android动态加载框架汇总

    几种动态加载的比较 1.Tinker 用途:热修复 GitHub地址:https://github.com/Tencent/tinker/ 使用:http://www.jianshu.com/p/f6 ...

  8. 为不同分辨率单独做样式文件,在页面头部用js判断分辨率后动态加载定义好的样式文件

    为不同分辨率单独做样式文件,在页面头部用js判断分辨率后动态加载定义好的样式文件.样式文件命名格式如:forms[_屏幕宽度].css,样式文件中只需重新定义文本框和下拉框的宽度即可. 在包含的头文件 ...

  9. html中的图像动态加载问题

    首先要说明下文档加载完成是什么概念 一个页面http请求访问时,浏览器会将它的html文件内容请求到本地解析,从窗口打开时开始解析这个document,页面初始的html结构和里面的文字等内容加载完成 ...

随机推荐

  1. 图解HTTP总结(6)——HTTP首部

    HTTP报文首部 HTTP 协议的请求和响应报文中必定包含 HTTP 首部. 首部内容为客户端和服务器分别处理请求和响应提供所需要的信息. 对于客户端用户来说, 这些信息中的大部分内容都无须亲自查看. ...

  2. python文件操作练习之文件备份

    文件备份 ## 文件备份 # 打开文件 def backup(file1, file2): with open(file1, 'rb') as f1,\ open(file2, 'wb') as f2 ...

  3. scrapy之分布式

    分布式爬虫 概念:多台机器上可以执行同一个爬虫程序,实现网站数据的分布爬取. 原生的scrapy是不可以实现分布式爬虫? a) 调度器无法共享 b) 管道无法共享 工具 scrapy-redis组件: ...

  4. iptables v1.3.5: multiple -d flags not allowed错误已解决

    今天写了一条iptables的规则 iptables -t filter -A INPUT -s 192.168.192.0/24 -d 192.168.192.140 -p tcp -dport 2 ...

  5. 九、MySQL 5.7.9版本sql_mode=only_full_group_by问题

    MySQL 5.7.9版本sql_mode=only_full_group_by问题 用到GROUP BY 语句查询时com.mysql.jdbc.exceptions.jdbc4.MySQLSynt ...

  6. SpringMVC---springMVC配置文件(springweb.xml)简介

    再web.xml中设置HTTP请求的中央调度处理器DispatcherServlet时,会指定SpringMVC配置文件,这里取名springweb.xml是因设置DispatcherServlet时 ...

  7. 从库函数操作RCC的流程来理解偏移变量

    下面是库函数操作RCC流程,看完后有我的疑问:偏移地址的理解 1,库函数直接操作:RCC库函数操作  RCC_APB2PeriphClockCmd ()RCC->APB2ENR |= RCC_A ...

  8. Kafka安装和常用操作命令

    Kafka安装: 下载kafka_2.10-0.8.2.1 1.关闭防火墙 2.修改配置文件  server.properties broker.id=1log.dirs= /usr/kafka_2. ...

  9. CSS3 3D圆形设计教程

    http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201502061338.html

  10. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目7

    2014-03-20 03:35 题目:实现画图的Flood Fill操作. 解法:DFS和BFS皆可,但BFS使用的队列在时间复杂度上常数项比较大,速度略慢,所以我选了DFS.当然,如果图很大的话D ...