简单模板模式

概念介绍

简单模板模式(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. MongoDB基本shell操作

    ---------------------MongoDB基本操作--------------------- 1.MongoDB创建数据库     use 数据库名:切换到指定的数据库中,在插入第一个条 ...

  2. keepalive之LVS-DR架构

    author:JevonWei 版权声明:原创作品 Keepalive实战之LVS-DR 实验目的:构建LVS-DR架构,为了达到LVS的高可用目的,故在LVS-DR的Director端做Keepal ...

  3. Phpstorm中使用SFTP

    Phpstorm中经常会出现FTP连接失败的问题,这个时候我们可以使用SFTP来连接服务器. 1.添加服务器.tools--deployment--configuration/browse Remot ...

  4. windows.onload和 document.ready区别

    在Jquery里面,我们可以看到两种写法:$(function(){}) 和$(document).ready(function(){}) 这两个方法的效果都是一样的,都是在dom文档树加载完之后执行 ...

  5. Spring 设置readonly 事务只读模式

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt394 在学习spring事务的时候,发现设置readOnly后不启作用. 查 ...

  6. 团队作业9——展示博客(Bata版本)

    1.团队成员介绍及项目地址 团队的源码仓库地址:https://coding.net/u/app24dian/p/app24dian/git 陈麟凤:(http://www.cnblogs.com/c ...

  7. 201521123061 《Java程序设计》第四周学习总结

    201521123061 <Java程序设计>第四周学习总结 1. 本章学习总结 (1)思维导图: --- (2)上课内容总结: 第四周学习了Java中的继承与多态,思维导图中已经给出了本 ...

  8. 201521123005 《Java程序设计》 第十一周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 Q1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  9. 201521123011《Java程序设计》 第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  10. Eclipse rap 富客户端开发总结(13) :Rap/Rcp保存按钮处理方式

    一.概述 在做项目的过程中,处理编辑区的保存机制的时候.发现,同样是扩展eclipse 自带的保存和全部保存按钮时候,rcp 工程下,保存按钮可以正常的灰显和可用,但是rap 的按钮就是始终呈现灰显的 ...