简单模板模式

概念介绍

简单模板模式(Simple template): 通过格式化字符串拼凑出视图避免创建视图时大量节点操作,优化内存开销。

创建模板

在实际的业务中如果我们需要进行前后台交互,或多或少会遇到需要把后台数据,绑定到我们通过js生成的html里,然后再展示到页面上的需求,比如现在我要生成如下样式并展示到页面上。



首先我们肯定会分析这个页面的结构然后去创建相应的节点并在页面中展示,比如像下面这样

//我们可以创建一个模板类的命名空间
var T=T||{};
//我们接着创建一个根节点,我们需要生成的模板会在这个节点下显示
T.root=document.getElementById('container');
//我们创建一个集合存储模板
T.TempFactory={
'listTemp':function(data){
//创建最外层的容器
var d=document.createElement("div"),
//接着创建下级的标题容器
h=document.createElement("h2"),
//标题下面的段落容器
p=document.createElement("p"),
//向标题容器中添加内容
ht=document.createTextNode(data.data.h2),
//向段落容器中添加内容
pt=document.createTextNode(data.data.p),
//创建列表容器
ul=document.createElement("ul"),
//获取数据中的li标签
ldata=data.data.li,
//依次是li元素,strong元素,span元素,填充strong内容,填充span内容
li,strong,span,t,c;
//如果数据里存在ID就给最外层容器赋值ID
data.id&&(d.id=data.id);
//向标题里追加内容
h.appendChild(ht);
//向段落里追加内容
p.appendChild(pt);
//把标题添加到最外层的容器里
d.appendChild(h);
//把段落添加到最外层的容器里
d.appendChild(p);
//循环添加数据中的列表
for (var i=0;i<ldata.length;i++) {
//创建li标签
li=document.createElement("li");
//创建strong标签
strong=document.createElement("strong");
//创建span标签
span=document.createElement("span");
//向strong标签中添加内容
t=document.createTextNode(ldata[i].strong);
//向span标签中添加内容
c=document.createTextNode(ldata[i].span);
//把内容追加进strong标签
strong.appendChild(t);
//把内容追加进span标签
span.appendChild(c);
//把strong标签追加进li标签
li.appendChild(strong);
//把span标签追加进li标签
li.appendChild(span);
//把li标签追加到ul标签下
ul.appendChild(li);
}
//像我们最外层的容器中添加李彪
d.appendChild(ul);
//最后把创建的模板插入到我们之前创建的根节点下
T.root.appendChild(d);
}
}
//增加初始化方法
T.init=function(data){
this.TempFactory[data.type](data);
}

好的我们创建好了模板试着模拟数据调用一下

var datas={id:"test",type:"listTemp",data:{h2:"标题",p:"内容",li:[{strong:"加粗列表内容",span:"列表内容"},{strong:"加粗列表内容2",span:"列表内容2"}]}}

T.init(datas);

好了,我们看到我们的功能实现了,但是我们发现我们创建一个这么简单页面就要创建这么多节点看上去相当复杂而且麻烦,那我们如何去优化呢?这个时候我们就可以去试着优化模板,来简化我们的操作,我们还可以用一些占位符代替模板中需要填充的内容,到时候利用正则我们可以把占位符替换成对应的内容。

优化模板

首先我们需要添加一个方法把占位符变成我们的内容

T.formateString=function(str,data){
return str.replace(/\{{(\w+)\}}/g,function(match,key){
return typeof data[key]===undefined ? '' : data[key]
})
}

接着我们开始修改我们之前臃肿的模板

'listTemp':function(data){
var d=document.createElement("div"),
ul="",
ldata=data.data.li,
//前面的方式还是不变这里,我们把这个改成模板。用{{}}充当占位符
tpl=[
'<h2>{{h2}}</h2>','<p>{{p}}</p>','<p>{{ul}}</p>'
].join(''),
//这里也是一样的这里是ul里的标签
liTpl=[
'<li>','<strong>{{strong}}</strong>','<span>{{span}}</span>','</li>'
].join('');
data.id&&(d.id=data.id);
//遍历列表数据
for (var i=0;i<ldata.length;i++) {
//如果列表有数据
if (ldata[i].strong||ldata[i].span) {
//列表字符串追加一项列表项
ul+=T.formateString(liTpl,ldata[i]);
}
}
//填充列表数据数据
data.data.ul=ul;
//用我们的替换方法渲染模块并插入我们的外层容器中
d.innerHTML=T.formateString(tpl,data.data);
//绑定到根节点下
T.root.appendChild(d);
}

好了我们再来看看

var datas={id:"test",type:"listTemp",data:{h2:"标题",p:"内容",li:[{strong:"加粗列表内容",span:"列表内容"},{strong:"加粗列表内容2",span:"列表内容2"}]}}

T.init(datas);



经过我们的优化是不是减少了很对对页面中节点的操作,但是我们发现我们这个模板还有相似之处我们还可以接着优化。

再次优化模板

我们的模板虽然简化了很多,但是我们发现标签占位符的结构都很相似,那么我们就可以把他们提出来,再次优化

我们可以把公共的地方提取出来创建一个模板生成器

//模板生成器
T.view=function(name){
//如果参数是一个数组,则返回多行模板
if(Object.prototype.toString.call(name)==="[object Array]"){
//模板缓存器
var tpl='';
//遍历标识
for(var i=0;i<name.length;i++){
//模板缓存器追加模板
tpl+=arguments.callee(name[i]);
}
//返回最终模板
return tpl;
}else{
//返回建议模板
return '<'+name+'>{{'+name+'}}</'+name+'>';
}
}

我们在修改一下之前的模板

T.TempFactory={
'listTemp':function(data){
var d=document.createElement("div"),
ul="",
ldata=data.data.li,
//这里用我们的模板生成器修改一下
tpl=T.view(['h2','p','ul']),
liTpl=T.formateString(T.view('li'),{li:T.view(['strong','span'])});
data.id&&(d.id=data.id);
for (var i=0;i<ldata.length;i++) {
if (ldata[i].em||ldata[i].span) {
ul+=T.formateString(liTpl,ldata[i]);
}
}
data.data.ul=ul;
d.innerHTML=T.formateString(tpl,data.data);
T.root.appendChild(d);
}
}

我们在看看

var datas={id:"test",type:"listTemp",data:{h2:"标题",p:"内容",li:[{strong:"加粗列表内容",span:"列表内容"},{strong:"加粗列表内容2",span:"列表内容2"}]}}

T.init(datas);

总结

简单模板模式主要解决御用DOM操作创建视图时造成资源消耗大、性能底下、操作复杂等问题。用正则的方式去格式化字符串执行的性能高于DOM操作拼接视图的执行性能。

也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~

好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。

欢迎转载,转载请注明作者,原文出处。

再起航,我的学习笔记之JavaScript设计模式30(简单模板模式)的更多相关文章

  1. 再起航,我的学习笔记之JavaScript设计模式05(简单工程模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  2. 再起航,我的学习笔记之JavaScript设计模式05(简单工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  3. 再起航,我的学习笔记之JavaScript设计模式06(工厂方法模式)

    上一次已经给大家介绍了简单工厂模式,相信大家对创建型设计模式有了初步的了解,本次我将给大家介绍的是工厂方法模式. 工厂方法模式 工厂方法模式(Factory Method):通过对产品类的抽象使其创建 ...

  4. 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  5. 再起航,我的学习笔记之JavaScript设计模式07(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  6. 再起航,我的学习笔记之JavaScript设计模式13(装饰者模式)

    装饰者模式 装饰者模式(Decorator): 在不改变原对象的基础上,通过对其进行过包装拓展(添加属性高或者方法)使原有对象可以满足用户的更复杂需求. 如果现在我们有个需求,需要做一个提交表单,当我 ...

  7. 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)

    中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...

  8. 再起航,我的学习笔记之JavaScript设计模式16(享元模式)

    ### 享元模式 **享元模式(Flyweight):** 运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销. 上回我们在组合模式中创建了文章列表类,这次我们要向不同的文 ...

  9. 再起航,我的学习笔记之JavaScript设计模式02

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

随机推荐

  1. C++三种野指针及应对/内存泄露

     野指针,也就是指向不可用内存区域的指针.如果对野指针进行操作,将会使程序发生不可预知的错误,甚至可能直接引起崩溃.         野指针不是NULL指针,是指向"垃圾"内存的指 ...

  2. 浅析SQL Server在可序列化隔离级别下,防止幻读的范围锁的锁定问题

    本文出处:http://www.cnblogs.com/wy123/p/7501261.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  3. display:inline-block间隙问题

    display:inline-block 是让块级元素变成行内元素 在一行显示, 然而不幸的是,它并没有得到所有浏览器的支持,比如ie6.7和古老一点的firefox完全无视它,由于firefox的老 ...

  4. Spring中ApplicationContextAware的用法

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt379 一.这个接口有什么用? 当一个类实现了这个接口(Application ...

  5. Android微信登录、分享、支付

    转载需要著名出处: http://blog.csdn.net/lowprofile_coding/article/details/78004224 之前写过微信登录分享支付第一版: http://bl ...

  6. Mybatis源码解析-BoundSql

    mybatis作为持久层,其操作数据库离不开sql语句.而BoundSql则是其保存Sql语句的对象 前提 针对mybatis的配置文件的节点解析,比如where/if/trim的节点解析可见文章Sp ...

  7. 看懂c/c++ 函数、指针、数组定义

    读懂 函数 + 指针 + 数组 c语言运算符机器优先级,看这里 结合运算符优先级,我们试着读懂函数和指针 优先级简单看 表达式提升():一级优先 函数():二级优先 数组[]:二级优先 指针定义*:三 ...

  8. 201521123110 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1.clone方法 1.1 Object对 ...

  9. 201521123088《Java程序设计》第6周学习总结

    1. 本周学习总结 2. 书面作业 clone方法1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么?                 ...

  10. 201521123032 《Java程序设计》第1周学习总结

    #1. 本周学习总结 下载熟悉eclipse,了解java的入门.用notepad++和eclipse编写Java程序.复习到了十进制转化为二进制,八进制与十六进制. #2. 书面作业 ##2.1为什 ...