您的位置:首页 > 其它

设计模式知识连载(47)---Widget模式:

2018-01-07 23:58 567 查看
<body>

<h3>设计模式知识连载(47)---Widget模式:</h3>
<div>
<p>
(Web Widget指的是一块可以在任意页面中执行的代码块)Widget模式是指借用Web Widget思想将页面分解成部件,针对部件开发,最终组合成完整的页面。
</p>
</div>

<hr>

<!--===============模板种类开始===========-->
<!-- 页面元素内容 -->
<div id='demo_tag' class="template">
<div id="tag_cloud">
{% for(var i = 0; i < tagCloud.length; i++){
var ctx = tagCloud[i];
%}
<a href="#" class="tag_item {% if(ctx['is_selected']) { %}selected{% } %}" title="{%=ctx['title']%}">
{% =ctx['text'] %}
</a>
{% } %}
</div>
</div>

<!-- 表单元素内的内容 -->
<textarea id="demo_textarea" class="template">
<div id="tag_cloud">
{%  for(var i = 0; i < tagCloud.length; i++) {
var ctx = tagCloud[i]; %}
<a href="#" class="tag_item
{% if(ctx['is_selected']){ %}
selected
{% } %} " title="{%=ctx['title']%}">
{% =ctx[text] %}
</a>
{% } %}
</div>
</textarea>

<!-- srcpt模板内容 -->
<script type="text/template" id="demo_script">
<div id="tag_cloud">
{% for(var i = 0; i < tagCloud.length; i++){
var ctx = tagCloud[i] ; %}
<a href="#" class="tag_item
{% if(ctx['is_selected']){ %}
selected
{% } %}" title="{%=ctx['title']%}">{%=ctx['text']%}
</a>
{% } %}
</div>
</script>

<!-- 自定义模板 -->
<!--===============模板种类结束===========-->

<script type="text/javascript">

// 模拟数据
var data = {
tagCloud : [
{is_selected : true, title : '这是一本设计模式书', text : '设计模式'},
{is_selected : false, title : '这是一本HTML', text : 'HTML'},
{is_selected : null, title : '这是一本CSS', text : 'CSS'},
{is_selected : '', title : '这是一本javascript', text : 'javascript'},
]
}

/**
*   案例一:视图模块化,方式一:初始
*/

/*===============实现原理开始===========*/
/****
*   模板:
*   <a href = '#' class = 'data-lang{%if(is_selected){%}selected{%}%}' value = '{%=value%}'>{%=text%}</a>
****/
/****
*   数据:
*   {is_selected : true, value : 'zh', text : 'zh-text'}
****/
/****
*   输出结果:
*   <a href = '#' class = 'data-lang selected' value = 'zh'>zh-text</a>
****/
/*===============实现原理结束===========*/

/*===============模板引擎模块开始===========*/
// 模板引擎模块
F.module('lib/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)
// 转义标签内的<如:<div>{%if(a<b)%}</div> -> <div>{%if(a<b)%}</div>
.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 ;
}) ;

/*######fnBody分析开始######*/
// "// 声明template_array模板容器组
// var template_array = [] ; \n
// // 闭包,模板容器组添加成员
// var fn = (function(data) { \n
//  // 渲染数据变量的执行函数体
//  var template_key = '' ; \n
//  // 遍历渲染数据
//  for(key in data) { \n
//      // 为渲染数据变量的执行函数体添加赋值语句
//      template_key += ('' + key + '=data[\"'+ key +'\"] ;') ; \n
//  } \n
//  // 执行渲染数据变量函数
//  eval(template_key) ; \n
//  // 为模板容器组添加成员(注意,此时渲染数据将替换容器中的变量)
//  template_array.push('"+ _dealTpl(str) +"') ; \n
//  //释放渲染数据变量函数
//  template_key = null ; \n
// // 为闭包传入数据
// })(templateData) ; \n
// // 释放闭包
// fn = null ; \n
// // 返回渲染后的模板容器组,并拼接成字符串
// return template_array.join('') ;"
/*######fnBody分析结束######*/

// 使用时,只需引用模板引擎模块依赖就可以
F.module(['lib/template', 'lib/dom'], function(template, dom) {
// 服务器端获取到data数据逻辑
// 创建组件视图逻辑
var str = template('demo_script', data) ;
dom.html('test', str) ;
// 组件其他交互逻辑
}) ;
/*===============模板引擎模块结束===========*/

/*===============模板种类结束===========*/
// 自定义模板
var demo_tpl = [
'<div id="tag_cloud">',
'{% for(var i = 0; i < tagCloud.length; i++){',
' var ctx = tagCloud[i]; %}',
'<a href="#" class="tag_item {% if(ctx["is_selected"]){ %}',
'selected',
'{% } %}" title="{%=ctx["title"]%}">',
'{%=ctx["text"]%}',
'</a>',

4000
'{% } %}',
'</div>'
].join('') ;
/*===============模板种类结束===========*/

</script>

</body>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息