每天一点点-EXT源码分析六

学习源码,痛苦又快乐的过程。
自己感觉,虽然EXT的模板模型和设计模式的模板模式的实现大相径庭,但它们思想都是一样的,把不变的部分与变化的部分相分离,以便不变的部分可以很好的复用。

来个小例子,比如某工业大学需要一个条幅,为了减缩支出,这个条幅需要是能反复使用的,也就是说,其上面的字是可以来回改的,但其打底的红布是不变的。

var s='<div style="width:200px;height:20px;background-color:red"><span style="color:black">{0}</span></div>';
var c=String.format(s,'欢迎XX莅临我校,吃好喝好');
document.write(c);
var c=String.format(s,"热烈庆祝我校清考业务收入创新高');
document.write(c);



Ext扩展了原生String,添加了format这个静态方法,看看其源码。
format : function(format){
        var args = Ext.toArray(arguments, 1);
        return format.replace(/\{(\d+)\}/g, function(m, i){
            return args[i];
        });
}

很容易理解,就是把第一个参数(字符串)中与{\d+}({0},{1}......)匹配的所有字符串依次替换成args[1],args[2]....
这样就把变与不变相分离了。

这个函数的能力太有限了,如果想对变的部分在插入时做些处理,这个函数显然无能为力。
EXT提供了俩个模板类
Ext.Template,Ext.util.Xtemplate。

先来看看Ext.Template类,它的实例方法非常的多,对于我来说也非常难懂,先关注其重要的2点。
先来看看这个类本身。
Ext.Template = function(html){
    var me = this,
        a = arguments,
        buf = [];

    if (Ext.isArray(html)) {
        html = html.join("");
    } else if (a.length > 1) {
        Ext.each(a, function(v) {
            if (Ext.isObject(v)) {
                Ext.apply(me, v);
            } else {
                buf.push(v);
            }
        });
        html = buf.join('');
    }


js的函数真的是非常繁杂的东西,它即可以当成一个对象的方法,又可以是本身的唯一的构造方法,同时它本身又是一个对象。
我理解的是,我们生成一个此类的对象时,和直接调用这个函数唯一的区别就是,new会返回一个此类的对象。

当我们new一个这个模板的对象,这个构造器大概做的事情就是分传参的不同情况,给它的对象添加一个html字符串,并且可以添加一个或多个函数或属性,这些函数,属性是非常有用的,它被用来当做格式化要插入的数据,它可以是自定义的(this.XX),也可以是Ext.util.format类的函数。
属性呢?它主要是一些解析过程的配置参数,如complied,disableFormat等

当我们有了这个模板实例后,就可以调用它的实例方法,此时就会应用动态数据把变的部分传入,此时还会调用它的格式化函数来格式化动态数据,并且显示到我们想让它出现的地方。
拿append实例方法来说明。

append : function(el, values, returnElement){
        return this.doInsert('beforeEnd', el, values, returnElement);
 },

可以看到此时又调用了实例方法-doInert

doInsert : function(where, el, values, returnEl){
        el = Ext.getDom(el);
        var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
        return returnEl ? Ext.get(newNode, true) : newNode;
},

又可以看出,doInset主要把是已经生成为HTML字符串定位到哪里(把其放到DOM文档的哪里,这个HTML字符串是由 applyTemplate(values)生成的),而传入动态数据和格式化传入数据,并且返回这个已经填充好内容的具体模板(HTML字符串)的功能是applyTemplate(values)完成

来看看这个applyTemplate(values),嗯,这个函数又碉堡了,现在还看得很模糊,因为正则表达式比较学得比较烂,尤其fn那里,Jack Slocum。。。。

Ext.apply(Ext.Template.prototype, {

    applyTemplate : function(values){

        var me = this,//模板实例

            useF = me.disableFormats !== true,//模板对象的一个属性判断可否数据可否格式化

            fm = Ext.util.Format, 

            tpl = me;           

        if(me.compiled){//先不管这段代码,以后讨论,它是为提高性能的

            return me.compiled(values);

        }

        function fn(m, name, format, args){//内联函数,作为String.replace的回调函数,所以其参数格式是固定的
                                                               

           
               if (format && useF) {//模板实例里是否有format函数,

                if (format.substr(0, 5) == "this.") {//如果是自定义的格式化参数

                    return tpl.call(format.substr(5), values[name], values);//执行

                } else {//处理Ext.util.Format里的函数

                    if (args) {//解析对应Ext.util.Format传入的参数
                        var re = /^\s*['"](.*)["']\s*$/;

                        args = args.split(',');

                        for(var i = 0, len = args.length; i < len; i++){

                            args[i] = args[i].replace(re, "$1");

                        }

                        args = [values[name]].concat(args);

                    } else {

                        args = [values[name]];

                    }

                    return fm[format].apply(fm, args);//执行

                }

            } else {

                return values[name] !== undefined ? values[name] : "";

            }

        }

        return me.html.replace(me.re, fn);//替换变的部分

    },










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值