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

本文详细探讨了设计模式中的Widget模式,重点解析其在Web开发中的应用,阐述了如何使用Widget模式增强页面组件的复用性和灵活性,同时讨论了其实现原理和最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<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&lt;b)%}</div> -> <div>{%if(a<b)%}</div>
                .replace(/&lt;/g, '<')
                // 转义标签内的>
                .replace(/&gt;/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>',
        '{% } %}',
        '</div>'
        ].join('') ;
    /*===============模板种类结束===========*/


</script>    




</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值