简单模板模式

概念介绍

简单模板模式(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. github如何添加ssh

    1.运行git Bash 输入如下命令: $ cd ~/.ssh $ ls 输入这2个命令 ,我们可以看到 id_rsa.pub 或 id_dsa.pub 这2个文件已经存在了,id_rsa 是私钥, ...

  2. node.js 下载安装及gitbook环境安装、搭建

    最近需要gitbook看文档,于是各种百度,各种安装,很多都是无法正常安装完成的,比较纠结啊 最后,终于发现一个好用的,现分享一下地址(也是给自己做个记录): 1.node.js下载地址: http: ...

  3. SVG裁切和蒙版

    前面的话 本文将详细介绍SVG裁切和蒙版 裁剪 SVG中的<clipPath>的元素,专门用来定义剪裁路径.必须设置的属性是id属性,被引用时使用 下面是一个圆形 <svg heig ...

  4. Java GC 日志详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt105 java GC日志可以通过 +PrintGCDetails开启 以Pa ...

  5. 遇到的一些Jquery函数

     jQuery.extend()        jQuery.merge():函数用于合并两个数组内容到第一个数组. <script> $(function () { ,,], [,,] ...

  6. 工作常用git命令

    克隆项目 git clone gitssh地址 提交前的准备 git config user.name 您的中文名 git config user.email 公司邮箱 获取分支 #### 将远端分支 ...

  7. 201521123070 《JAVA程序设计》第9周学习总结

    1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 Q1. 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 ...

  8. log4j 日志脱敏处理 + java properties文件加载

    Java 加载Properties 配置文件: ResourceBundle bundle = ResourceBundle.getBundle("log4j_filter"); ...

  9. python os语法

    前几天做了一个文件替换功能用到些python os的功能,感觉python os模块的功能非常的强大, 如果你希望你的python程序能够与平台无关的话,这个模块是尤为重要的.即它允许一个程序在编写后 ...

  10. 源码安装H2O Http 服务端程序到Ubuntu服务器

    首先安装全家桶 apt install -y build-essential zlib1g-dev libpcre3 libpcre3-dev unzip cmake libncurses5-dev ...