在开发WEB前端页面时,经常会根据动态的数据加载一些HTML控件,如果把这些HTML代码全写入JS中,根据不同的数据显示的控件也不一样,操作起来会显得比较繁琐,而且极不利于代码的维护,怎么办呢?现在就是我要说的,使用模板方法,直接把数据往里面套就好了。废话不多说,以示例来说明。
先写个非常重要的JS方法,此方法就是用来填充格式数据的。(看不懂也没关系,会用就行)
function formatTemplate(dta, tmpl) { var format = { name: function(x) { return x } }; return tmpl.replace(/{(\w+)}/g, function(m1, m2) { if (!m2) return ""; return (format && format[m2]) ? format[m2](dta[m2]) : dta[m2]; }); }
接下来就用示例来说明:
例如:从服务器取出一个JSON串,把数据显示在一组HTML控件上,现在我先把HTML代码写下来:
<script type="text/template"> <tr mgid="{mgid}" mid="{mid}"> <td> <input type="checkbox" mid="{mid}"></td> <td> <a href="{localfile}" data-fancybox-group="button" class="fancybox-buttons"> <img src="{localfile}" style="width:45px;height:45px;"></a> </td> <td> <input type="text" class="input-large valid" value="{medianame}" onblur="TextOnBlur(this)" onclick="TextOnFocus(this)" name="medianame" mid="{mid}" readonly="readonly"></td> <td> <a onclick="updateMediaName(this)" href="javascript:void(0);">重命名</a> <a onclick="showbulkUploadTemplate(this)" name="edit" localfile="{localfile}" href="javascript:void(0);">替换</a> <a onclick="daleteMedia(this)" href="javascript:void(0);">删除</a> <a onclick="setMediaFaceImage(this);" title="设置为分组【{groupname}】的封面" groupname="{groupname}" mid="{mid}" href="javascript:void(0);">设置封面</a> </td> </tr> </script>
大家看到了这段代码,如果全部写JS上确实比较烦,而且大家也发现了,为什么在首尾有<script>标签,里面有{}括号括住了一些值,为什么这么写呢,别急别急。其实这些{}号中的数据,就是我们要填充的数据的地方。括号中的名称就是存贮值的变量,好,要怎么填呢?
若我们从服务器上取到的JSON如下:
{ "total": "1", "page": "1", "records": "3", "rows": [{ "groupname": "美食图片", "mid": 4766, "sid": 517, "medianame": "Tulips", "mgid": 549, "mediatype": "image", "mediaid": "", "timestamp": "", "localfile": "/UploadFile/image/201409/14/0x6dvf.jpg", "picurl": "", "thumbid": "", "voiceformat": "", "state": 1, "createtime": "\/Date(1410673220000+0800)\/", "uploadtime": "\/Date(1410673220000+0800)\/", "width": 480, "height": 360, "seizespace": 17.41 }, { "groupname": "美食图片", "mid": 4765, "sid": 517, "medianame": "Penguins", "mgid": 549, "mediatype": "image", "mediaid": "", "timestamp": "", "localfile": "/UploadFile/image/201409/14/6iluw6.jpg", "picurl": "", "thumbid": "", "voiceformat": "", "state": 1, "createtime": "\/Date(1410673215000+0800)\/", "uploadtime": "\/Date(1410673215000+0800)\/", "width": 480, "height": 360, "seizespace": 15.62 }, { "groupname": "美食图片", "mid": 4764, "sid": 517, "medianame": "Lighthouse", "mgid": 549, "mediatype": "image", "mediaid": "", "timestamp": "", "localfile": "/UploadFile/image/201409/14/fx0kzp.jpg", "picurl": "", "thumbid": "", "voiceformat": "", "state": 1, "createtime": "\/Date(1410673209000+0800)\/", "uploadtime": "\/Date(1410673209000+0800)\/", "width": 480, "height": 360, "seizespace": 14.2 }] }
我们要填写到地方定义在下面Table中
<html> <body> <table id="tableData"> <tr class="firstLine"> <th></th> <th>图片</th> <th>图片名称</th> <th>类型</th> <th>大小</th> <th>尺寸</th> <th>上传日期</th> <th>操作</th> <th></th> </tr> </table> </body> </html>
好了准备工作做好了,重点的来了,别看走眼了:
$.ajax({ url: '/manage/GetAllMediaListPage', type: 'get', data: data, cache: false, dataType: "json", success: function(dta) { if (!dta || !dta.rows || dta.rows.length <= 0) { return; } //获取模板上的HTML var html = $('script[type="text/template"]').html(); //定义一个数组,用来接收格式化合的数据 var arr = []; //对数据进行遍历 $.each(dta.rows, function(i, o) { //这里取到o就是上面rows数组中的值, formatTemplate是最开始定义的方法. arr.push(formatTemplate(o, html)); }); //好了,最后把数组化成字符串,并添加到table中去。 $('#tableData').append(arr.join('')); //走完这一步其实就完成了,不会吧,这么简单,不错,就是这么简单!! 不信就自己动手去试试! } });
哟嚯,搞定,等等,好像表格的列数对不上,是吧,那是因为我没有把模板写完整出来,继续往下看。
现在我来解释为什么把模板代码放在<script></script>中间,假如,你把模板代码放在某个<div>中并隐藏起来,那么可能你的代码中会用到$('input[type="text"]')查找控件时,不好意思,就会把模板中的也统计进去了,这个并不是你想要的。所以我用<script>,这么做还有一个好处,就是不会被当成HTML来执行显示出来, 但我们也得保证不能当成js来执行,所以加了个type="text/template",没有这个类型的,自己明白就好了。
另外,像o.mid的数值只会填充到{mid}这个里,不会填充到别的地方去,而且{mid}可以存在多个,一并全部替换成实际数值了。
接下来的一个问题就是,我取到的数据可能并不是我要给用户显示的,那么就需要变通一下了
var html = $('script[type="text/template"]').html(); var arr = []; $.each(dta.rows, function(i, o) { //atime,asize和fsize这三个变量是之前的JSON中没有的,可灵活设置一下: //格式化时间,当然getFormatDate这个函数我也公布出来了,格式化时间而已,见最后面。 o.atime = getFormatDate(o.uploadtime ? o.uploadtime : o.createtime, 'yyyy-MM-dd'); //图片的尺寸大小: 就是把上面的o.width和o.height变量组合一下,如果任何一个不存在,则返回"-" o.asize = (o.width && o.height) ? o.width + ' * ' + o.height : '-'; //图片大小。存在才显示xxKB o.fsize = o.seizespace ? o.seizespace + ' KB' : '-'; //格式化模板数据 arr.push(formatTemplate(o, html)); }); $('#tableData').append(arr.join(''));
完整的HTML模板如下:
<script type="text/template"> <tr mgid="{mgid}" mid="{mid}"> <td> <input type="checkbox" mid="{mid}"></td> <td> <a href="{localfile}" data-fancybox-group="button" class="fancybox-buttons"> <img src="{localfile}" style="width:45px;height:45px;"></a> </td> <td> <input type="text" class="input-large valid" value="{medianame}" onblur="TextOnBlur(this)" onclick="TextOnFocus(this)" name="medianame" mid="{mid}" readonly="readonly"></td> <td>{mediatype}</td> <!-- 各位看官,自定义的三个属性在这里哦~~ --> <td>{fsize}</td> <td>{asize}</td> <td>{atime}</td> <td> <a onclick="updateMediaName(this)" href="javascript:void(0);">重命名</a> <a onclick="showbulkUploadTemplate(this)" name="edit" localfile="{localfile}" href="javascript:void(0);">替换</a> <a onclick="daleteMedia(this)" href="javascript:void(0);">删除</a> <a onclick="setMediaFaceImage(this);" title="设置为分组【{groupname}】的封面" groupname="{groupname}" mid="{mid}" href="javascript:void(0);">设置封面</a> </td> </tr> </script>
其实想通了还是挺简单的,当然formatTemplate函数中的第一个参数必须要求是像struct的对象,直接一点就是这样一个数据包: { "A": “a”, "B": "b", "C":"c" } 。懂了吧伙计们,不懂就慢慢看吧,嘿嘿!
附: 格式化时间函数:
function getFormatDate(xdate, format) { try { var format = format || 'yyyy-MM-dd HH:mm:ss'; var date = (xdate instanceof Date) ? xdate : new Date(parseInt(xdate.replace('/Date(', '').replace(')/', ''), 10)); var lang = { 'M+': date.getMonth() + 1, 'd+': date.getDate(), 'H+': date.getHours(), 'm+': date.getMinutes(), 's+': date.getSeconds() }; if (/(y+)/.test(format)) { format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); } for (var key in lang) { if (new RegExp('(' + key + ')').test(format)) { format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? lang[key] : ('00' + lang[key]).substr(('' + lang[key]).length)); } } return format; } catch (e) { return '-'; } }
原创写作
相关推荐
呼伦贝尔市-鄂温克族自治旗-街道行政区划_150724_Shp数据-wgs84坐标系.rar
内容概要:本文详细介绍了用于Cruise纯电动汽车仿真的输入模板,该模板由8个表单组成,覆盖了从整车参数到计算输出的各个方面。每个表单都包含了关键参数的设置方法及其背后的逻辑,如校核清单、整车参数、电池参数、电机参数、传动系参数、制动轮胎参数、能量回收参数以及最终的计算输出。文中不仅提供了具体的参数定义和计算公式,还附有Python代码示例,帮助用户更好地理解和应用这些参数。此外,作者还分享了一些实用技巧,如防止参数遗漏的校验函数、处理电池温度效应的实际容量计算函数等。 适合人群:从事纯电动汽车仿真工作的工程师和技术人员,尤其是那些需要频繁处理复杂输入参数的人群。 使用场景及目标:① 提高纯电动汽车仿真工作的效率和准确性;② 规范参数收集流程,减少因参数错误导致的仿真失败;③ 提供详细的参数设置指导和代码实现,帮助用户更好地理解和应用Cruise仿真平台。 其他说明:本文不仅提供了一个全面的输入模板,还分享了许多实践经验,旨在帮助用户在实际工作中少走弯路,提高工作效率。
街道级行政区划shp数据,wgs84坐标系,直接下载使用。
街道级行政区划shp矢量数据,wgs84坐标系,下载直接使用
Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
内容概要:本文档是作者在bugku平台进行CTF(夺旗赛)杂项题目练习的解题思路总结,涵盖第25至33题。题目类型多样,包括但不限于隐写术、进制转换、音频分析、图像处理等。每道题都详细介绍了背景信息、解题步骤和所使用的工具,如Stegsolve用于图片隐写分析、Python脚本处理进制转换、Audacity解析音频中的摩尔斯电码等。通过这些实例,展示了如何运用各种技术手段解决实际问题,强调了理论与实践相结合的重要性。 适合人群:对信息安全、逆向工程感兴趣的读者,特别是有一定编程基础和技术积累的安全爱好者或初学者。 使用场景及目标:①学习隐写术的基本原理及其在CTF比赛中的应用;②掌握不同进制间的转换方法及其实现;③熟悉音频文件中提取摩尔斯电码的技术;④了解图像处理技巧,如调整尺寸、解析隐藏信息等;⑤掌握压缩文件的明文攻击技巧,以及如何利用已知信息破解加密文件。 阅读建议:由于每道题涉及的知识点较为独立且专业性强,建议读者根据自己的兴趣选择相关题目深入研究。同时,在学习过程中应注重动手实践,尝试复现文中提到的操作流程,并结合网络资源进一步拓展知识面。对于遇到的工具和概念,可以通过查阅官方文档或参考教程加深理解。
内容概要:本文详细介绍了如何在Qt中实现一个高效的时间标尺控件,重点讲解了时间标尺的缩放功能、刻度自动生成以及曲线绘制的技术细节。首先,通过重载wheelEvent方法,利用QGraphicsView框架实现了基于鼠标的缩放功能,确保缩放过程中鼠标位置对应的时间点不变。其次,针对不同的时间范围,采用对数分级算法自动调整刻度间隔,使刻度线既美观又实用。最后,在曲线绘制方面,使用QPainterPath进行路径构建,并通过预处理和分段绘制优化性能,确保即使面对大量数据点也能保持流畅的用户体验。 适合人群:具有一定Qt开发经验的程序员,尤其是从事数据可视化项目的开发者。 使用场景及目标:适用于需要展示时间序列数据的应用程序,如金融图表、监控系统、日志分析工具等。主要目标是提供一个响应迅速、视觉效果优秀的交互式时间标尺控件,帮助用户更好地理解和分析数据。 其他说明:文中还提到了一些性能优化的小技巧,如数据预处理、路径分段绘制等,有助于提高大型数据集的渲染速度。同时,作者强调了在时间转换函数中避免使用低效的方法,推荐自行实现高效的缓存机制。
街道级行政区划shp数据,wgs84坐标系,直接下载使用。
街道级行政区划shp数据,wgs84坐标系,直接下载使用。
赤峰市-喀喇沁旗-街道行政区划_150428_Shp数据-wgs84坐标系.rar
内容概要:本文详细介绍了使用Python和LSTM(长短期记忆网络)进行时间序列预测的方法及其应用场景。首先阐述了时间序列预测的重要性,指出传统ARIMA模型在处理复杂模式和长期依赖关系时的局限性,进而引出LSTM的优势。LSTM通过引入门控机制(输入门、遗忘门、输出门)和记忆单元,有效解决了长期依赖问题,能更好地捕捉时间序列中的复杂模式。接着,文章详细讲解了LSTM的工作原理,包括各个门控机制的作用和计算流程。随后,通过股票价格预测和气温预测两个案例,逐步演示了从环境搭建、数据准备(包括数据读取、归一化处理)、模型构建(使用Keras搭建LSTM模型)、模型编译、训练与评估到预测结果可视化的全过程。最后,文章总结了LSTM的关键技术和实现要点,并展望了其在自然语言处理、计算机视觉、生物学等领域的应用前景及未来研究方向。 适合人群:具备一定编程基础,尤其是对深度学习和时间序列预测感兴趣的开发者、数据科学家和研究人员。 使用场景及目标:①帮助读者掌握LSTM的基本原理和工作流程;②提供详细的Python实现步骤,包括环境配置、数据处理、模型搭建与训练;③通过具体案例展示LSTM在时间序列预测中的应用,如股票价格预测和气温预测;④探讨LSTM在其他领域的潜在应用,如自然语言处理、计算机视觉和生物学等。 阅读建议:本文内容详尽,涵盖理论与实践两方面,建议读者在阅读过程中结合代码实践,逐步理解LSTM的工作原理和实现细节,特别是注意数据处理和模型参数的选择对预测效果的影响。
内容概要:本文详细介绍了基于三菱FX5U PLC的机床X轴和Y轴工作台定位控制系统的开发与优化过程。主要内容涵盖:使用J4-A系列伺服驱动器进行绝对位置控制,通过ST语言和结构化梯形图实现复杂的20组直线插补工序;手动模式下的点动与长按操作逻辑;MODBUS通讯协议的应用;以及详细的报警诊断和统计功能。文中展示了如何利用结构体封装参数,提高代码可读性和维护性,并通过具体案例解释了关键技术和调试经验。 适合人群:从事工业自动化控制领域的工程师和技术人员,尤其是熟悉三菱PLC编程的从业者。 使用场景及目标:适用于需要深入了解三菱FX5U PLC编程技巧及其在实际工程项目中应用的人群。目标是掌握高级编程方法如结构化编程、ST语言特性、MODBUS通讯优化等,从而提升工作效率并减少调试时间。 其他说明:文章不仅提供了理论知识,还包括大量实用的编程技巧和实践经验分享,有助于读者更好地理解和应用于实际工作中。
大同市-大同市-街道行政区划_140200_Shp数据-wgs84坐标系.rar
内容概要:本文详细介绍了火电厂协调仿真机的应用及其优势,特别是在PID参数调试方面的高效性和安全性。文中通过具体的Python代码示例展示了如何构建锅炉和汽轮机的仿真模型,并解释了PID控制器的工作原理。重点讨论了PID参数调试的关键点,如响应延迟、采样时间设定以及前馈控制的叠加效果。此外,还提到了实时曲线对比、参数扫描、自整定算法等功能的实际应用,强调了仿真机在提高调试效率和降低现场调试风险方面的重要作用。 适合人群:从事火电厂自动化控制领域的工程师和技术人员,尤其是需要进行PID参数调试的专业人士。 使用场景及目标:① 提高PID参数调试效率,减少现场调试时间和成本;② 降低现场调试的安全风险;③ 实现更加精确和平稳的控制系统性能。 其他说明:文章不仅提供了理论指导,还结合了大量的实战经验和具体代码示例,帮助读者更好地理解和掌握协调仿真机的使用方法。
街道级行政区划shp数据,wgs84坐标系,直接下载使用。
街道级行政区划shp数据,wgs84坐标系,直接使用。
学号-姓名-作业二编写程序.ipynb
正弦内插算法的FPGA实现.docx
街道级行政区划shp数据,wgs84坐标系,直接使用。