# Widget模式 `Widget`模式是指借用`Web Widget`思想将页面分解成组件,针对部件开发,最终组合成完整的页面,`Web Widget`指的是一块可以在任意页面中执行的代码块,`Widget`模式不属于一般定义的`23`种设计模式的范畴,而通常将其看作广义上的架构型设计模式。 ## 概述 模块化开发使页面的功能细化,逐一实现每个功能模块来完成系统需求,这是一种很好的编程实践,在简单模板模式实现的模板引擎的帮助下可以非常方便的完成这个实例,这将更适合多人团队开发,降低相互之间因为功能或者视图创建的耦合影响概率,组件的多样化也能够组建更加丰富的页面,同样也会让组件的复用率提高。 ## 实现 ```javascript // dom.js F.module("./dom", function() { return { g: function(id) { return document.getElementById(id); }, html: function(id, html) { if (!html) return this.g(id).innerHTML; else this.g(id).innerHTML = html; } } }); ``` ```javascript // template.js F.module("./template", function() { /*** * 模板引擎,处理数据的编译模板入口 * @param str 模块容器id或者模板字符串 * @param data 渲染数据 **/ var _TplEngine = function(str, data) { // 如果数据是数组 if (data instanceof Array) { // 缓存渲染模板结果 var html = ""; // 数据索引 var i = 0; // 数据长度 var len = data.length; // 遍历数据 for (; i < len; i++) { // 缓存模板渲染结果,也可以写成 // html += arguments.callee(str, data[i]) ; html += _getTpl(str)(data[i]); } // 返回模板渲染最终结果 return html; } else { // 返回模板渲染结果 return _getTpl(str)(data); } }; /*** * 获取模板 * @param str 模板容器id,或者模板字符串 **/ var _getTpl = function(str) { // 获取元素 var ele = document.getElementById(str); // 如果元素存在 if (ele) { // 如果是input或者textarea表单元素,则获取该元素的value值,否则获取元素的内容 var html = /^(textarea | input)$/i.test(ele.nodeName) ? ele.value : ele.innerHTML; // 编译模板 return _compileTpl(html); } else { // 编译模板 return _compileTpl(str); } }; // 处理模板 var _dealTpl = function(str) { // 左分隔符 var _left = "{%"; // 右分隔符 var _right = "%}"; // 显示转化为字符串 return String(str) // 转义标签内的<如:
{%if(a<b)%}
->
{%if(a .replace(/</g, "<") // 转义标签内的> .replace(/>/g, ">") // 过滤回车符,制表符,回车符 .replace(/[\r\t\n]/g, "") // 替换内容 .replace(new RegExp(_left + "=(.*?)" + _right, "g"), "',typeof($1) === 'undefined' ? '' : $1, '") // 替换左分隔符 .replace(new RegExp(_left, "g"), "');") // 替换右分隔符 .replace(new RegExp(_right, "g"), "template_array.push('"); }; /*** * 编译执行 * @param str 模板数据 **/ var _compileTpl = function(str) { // 编译函数体 var fnBody = "var template_array=[];\nvar fn=(function(data){\nvar template_key='';\nfor(key in data){\ntemplate_key +=(''+key+'=data[\"'+key+'\"];');\n}\neval(template_key);\ntemplate_array.push('" + _dealTpl(str) + "');\ntemplate_key=null;\n})(templateData);\nfn=null;\nreturn template_array.join('') ;"; // 编译函数 return new Function("templateData", fnBody); }; // 返回 return _TplEngine; }); ``` ```html Widget模式
``` ## 每日一题 ``` https://github.com/WindrunnerMax/EveryDay ``` ## 参考 ``` https://en.wikipedia.org/wiki/Web_widget https://segmentfault.com/a/1190000019541819 https://blog.csdn.net/yuzhiboyouzhu/article/details/78998860 ```