再起航,我的学习笔记之JavaScript设计模式30(简单模板模式)

简单模板模式

概念介绍

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

创建模板

在实际的业务中如果我们需要进行前后台交互,或多或少会遇到需要把后台数据,绑定到我们通过js生成的html里,然后再展示到页面上的需求,比如现在我要生成如下样式并展示到页面上。
774226-20171007233036568-1301630227.png
首先我们肯定会分析这个页面的结构然后去创建相应的节点并在页面中展示,比如像下面这样

//我们可以创建一个模板类的命名空间
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);
}

好的我们创建好了模板试着模拟数据调用一下
774226-20171007233036568-1301630227.png

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);

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

再次优化模板

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

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

//模板生成器
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);

774226-20171007233036568-1301630227.png

总结

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

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

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

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

转载于:https://www.cnblogs.com/chen-jie/p/JavaScript-Simple-Template.html

资源下载链接为: https://pan.quark.cn/s/ab08c24cda4d 本项目基于 PyTorch 实现了 CSRNet(卷积稀疏表示网络)人群计数模型。CSRNet 是一种高效且精准的人群密度估计方法,尤其适合高密度场景下的人群计数。该模型借助卷积神经网络(CNN)的特性,利用稀疏表示来应对复杂背景和密集人群的挑战。以下将详细介绍 CSRNet 的核心概念、结构及实现过程,并阐述人群计数的重要性。 人群计数在公共场所安全监控、交通管理和大型活动组织等领域极为关键。准确估计人群数量有助于保障安全和优化管理。传统计数方法如人工计数或基于规则的方法效率低且易出错而,深度学习技术的引入,尤其是 CSRNet 这类模型,显著提高了计数的准确性和效率。 CSRNet 的核心在于其深度卷积网络结构和稀疏表示能力。该模型通过多尺度特征提取,适应不同大小的人头。其架构包含多个卷积层,每层后接 Leaky ReLU 激活函数,增强非线性表达能力。此外,CSRNet 引入了空洞卷积(也称 atrous convolution),可在不增加参数数量的情况下扩大感受野,更高效地捕捉大范围信息。具体架构包括:输入层接收预处理后的图像;基础网络通常使用预训练的 VGG16 提取多层次特征;多尺度特征融合通过不同扩张率的空洞卷积获得不同分辨率的特征图;解码器利用反卷积操作将低分辨率特征图恢复至原始尺寸,结合多尺度信息重建上下文;稀疏表示层是 CSRNet 的独特之处,通过稀疏编码和解码,将高维特征转换为低维稀疏表示,降低背景噪声影响,提升人头检测精度;输出层通过 1×1 卷积将特征图转化为人群密度图,再经全局平均池化和全连接层得到最终计数结果。 在实现过程中,需注意以下几点:数据预处理,如缩放、归一化、增强等,以提升模型泛化能力;训练策略,包括数据集划分、学习率调度、损失函数选择(如
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值