`
xihuyu2000
  • 浏览: 32200 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ext.js(v2.1)源码分析

阅读更多
/**
* 1.Ext类是整个Ext体系的基础和核心,包含核心代码和函数。
* Ext类是单例的,不能直接创建。
*/

/**
  * 2.复制c中所有属性到o中,如果有defaults,属性也会复制到o中。
  * 如果defaults中的属性和c中相同,最后相同属性值是c中的。
  * 这里复制采用的是关联数组的形式。
  * @param {} o 目标对象
  * @param {} c 源对象
  * @param {} defaults 默认值对象
  * @return {} 返回目标对象
  */
Ext.apply = function(o, c, defaults){
    if(defaults){
        // no "this" reference for friendly out of scope calls
        Ext.apply(o, defaults);
    }
    if(o && c && typeof c == 'object'){
        for(var p in c){
            o[p] = c[p];
        }
    }
    return o;
};

/**
* 3.添加Function类原型的方法,也即添加属性给Function的原型。
* 这里一共两个参数,第一个是Function类的原型,第二个是直接量创建的对象。
* 第二个对象中有5个属性,每个属性都是一个方法。也即执行完后,每个函数的原型中都添加了这5个方法,可以随时调用。
*
* 第一个方法是createCallback,可以接受参数数组,表示window方位内的方法需要被回调,也即类方法被回调;因为类方法就是window对象的方法。
*
* 第二个方法是createDelegate,第一个参数是特定对象,表示特定对象的方法需要被回调,也即实例方法被回调,方法里面一定有具体的this引用,因为实例方法一般需要this引用。
* 当特定对象没有被指定时,就是window对象,这时等同于createCallback方法。
*
* 第三个方法是defer,第一个参数是延迟时间(单位毫秒),其余类似于createDelegate方法。内部使用setTimeout函数。
*
* 第四个方法是createSequence,接受两个参数,第一个是函数,第二个表示第一个参数的范围。两个函数使用相同的参数,调用函数先执行,然后执行形参函数,返回调用函数。
*
* 第五个方法是createInterceptor,形式参数与createSequence一样,但是形参函数先于调用函数执行。两个函数接受相同的参数,如果形参函数返回true,调用函数执行;否则,调用函数不执行。最终结果是调用函数的执行结果。
* 这个方法可以称作"前拦截",createSequence可以称作"后拦截"。
*/
Ext.apply(Function.prototype, {
     /**
     * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
     * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
     * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
     * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
     * executes in the window scope.
     * <p>This method is required when you want to pass arguments to a callback function.  If no arguments
     * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn). 
     * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
     * would simply execute immediately when the code is parsed. Example usage:
     * <pre><code>
var sayHi = function(name){
    alert('Hi, ' + name);
}

// clicking the button alerts "Hi, Fred"
new Ext.Button({
    text: 'Say Hi',
    renderTo: Ext.getBody(),
    handler: sayHi.createCallback('Fred')
});
</code></pre>
     * @return {Function} The new function
    */
    createCallback : function(/*args...*/){
        // make args available, in function below
        var args = arguments;
        var method = this;
        return function() {
            return method.apply(window, args);
        };
    },

    /**
     * Creates a delegate (callback) that sets the scope to obj.
     * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
     * callback points to obj. Example usage:
     * <pre><code>
var sayHi = function(name){
    // Note this use of "this.text" here.  This function expects to
    // execute within a scope that contains a text property.  In this
    // example, the "this" variable is pointing to the btn object that
    // was passed in createDelegate below.
    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
}

var btn = new Ext.Button({
    text: 'Say Hi',
    renderTo: Ext.getBody()
});

// This callback will execute in the scope of the
// button instance. Clicking the button alerts
// "Hi, Fred. You clicked the "Say Hi" button."
btn.on('click', sayHi.createDelegate(btn, ['Fred']));
</code></pre>
     * @param {Object} obj (optional) The object for which the scope is set
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
     *                                             if a number the args are inserted at the specified position
     * @return {Function} The new function
     */
    createDelegate : function(obj, args, appendArgs){
        var method = this;
        return function() {
            var callArgs = args || arguments;
            if(appendArgs === true){
                callArgs = Array.prototype.slice.call(arguments, 0);
                callArgs = callArgs.concat(args);
            }else if(typeof appendArgs == "number"){
                callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
                var applyArgs = [appendArgs, 0].concat(args); // create method call params
                Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
            }
            return method.apply(obj || window, callArgs);
        };
    },

    /**
     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
     * <pre><code>
var sayHi = function(name){
    alert('Hi, ' + name);
}

// executes immediately:
sayHi('Fred');

// executes after 2 seconds:
sayHi.defer(2000, this, ['Fred']);

// this syntax is sometimes useful for deferring
// execution of an anonymous function:
(function(){
    alert('Anonymous');
}).defer(100);
</code></pre>
     * @param {Number} millis The number of milliseconds for the setTimeout call (if 0 the function is executed immediately)
     * @param {Object} obj (optional) The object for which the scope is set
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
     *                                             if a number the args are inserted at the specified position
     * @return {Number} The timeout id that can be used with clearTimeout
     */
    defer : function(millis, obj, args, appendArgs){
        var fn = this.createDelegate(obj, args, appendArgs);
        if(millis){
            return setTimeout(fn, millis);
        }
        fn();
        return 0;
    },
   
    /**
     * Create a combined function call sequence of the original function + the passed function.
     * The resulting function returns the results of the original function.
     * The passed fcn is called with the parameters of the original function. Example usage:
     * <pre><code>
var sayHi = function(name){
    alert('Hi, ' + name);
}

sayHi('Fred'); // alerts "Hi, Fred"

var sayGoodbye = sayHi.createSequence(function(name){
    alert('Bye, ' + name);
});

sayGoodbye('Fred'); // both alerts show
</code></pre>
     * @param {Function} fcn The function to sequence
     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
     * @return {Function} The new function
     */
    createSequence : function(fcn, scope){
        if(typeof fcn != "function"){
            return this;
        }
        var method = this;
        return function() {
            var retval = method.apply(this || window, arguments);
            fcn.apply(scope || this || window, arguments);
            return retval;
        };
    },

    /**
     * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,
     * the original one is not called. The resulting function returns the results of the original function.
     * The passed fcn is called with the parameters of the original function. Example usage:
     * <pre><code>
var sayHi = function(name){
    alert('Hi, ' + name);
}

sayHi('Fred'); // alerts "Hi, Fred"

// create a new function that validates input without
// directly modifying the original function:
var sayHiToFriend = sayHi.createInterceptor(function(name){
    return name == 'Brian';
});

sayHiToFriend('Fred');  // no alert
sayHiToFriend('Brian'); // alerts "Hi, Brian"
</code></pre>
     * @param {Function} fcn The function to call before the original
     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
     * @return {Function} The new function
     */
    createInterceptor : function(fcn, scope){
        if(typeof fcn != "function"){
            return this;
        }
        var method = this;
        return function() {
            fcn.target = this;
            fcn.method = method;
            if(fcn.apply(scope || this || window, arguments) === false){
                return;
            }
            return method.apply(this || window, arguments);
        };
    }
});

/**
* 3.添加String类原型的方法,第一个参数是String类,可以添加的方法有3个。
*
* 第一个方法是escape,忽略某个字符串中的'和\,只有一个参数,表示特定字符串。
*
* 第二个方法是leftPad,表示左填充,第一个参数表示字符串,第二个参数表示最终的长度,第三个参数表示填充符号。
*
* 第三个方法是特定位置填充,特定位置使用{0}、{1}这样的表示方法,每个位置填充指定的字符串。第一个参数是格式化样式,后面的参数是需要被填充的字符串
*/
Ext.applyIf(String, {

    /**
     * Escapes the passed string for ' and \
     * @param {String} string The string to escape
     * @return {String} The escaped string
     * @static
     */
    escape : function(string) {
        return string.replace(/('|\\)/g, "\\$1");
    },

    /**
     * Pads the left side of a string with a specified character.  This is especially useful
     * for normalizing number and date strings.  Example usage:
     * <pre><code>
var s = String.leftPad('123', 5, '0');
// s now contains the string: '00123'
</code></pre>
     * @param {String} string The original string
     * @param {Number} size The total length of the output string
     * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
     * @return {String} The padded string
     * @static
     */
    leftPad : function (val, size, ch) {
        var result = new String(val);
        if(!ch) {
            ch = " ";
        }
        while (result.length < size) {
            result = ch + result;
        }
        return result.toString();
    },

    /**
     * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
     * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
     * <pre><code>
var cls = 'my-class', text = 'Some text';
var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
// s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
</code></pre>
     * @param {String} string The tokenized string to be formatted
     * @param {String} value1 The value to replace token {0}
     * @param {String} value2 Etc...
     * @return {String} The formatted string
     * @static
     */
    format : function(format){
        var args = Array.prototype.slice.call(arguments, 1);
        return format.replace(/\{(\d+)\}/g, function(m, i){
            return args[i];
        });
    }
});

/**
* 4.字符串工具类,如果第一个参数等于当前字符串,把第二个参数的值赋给当前字符串;如果不等,把第一个参数的值赋给当前字符串。
*/
String.prototype.toggle = function(value, other){
    return this == value ? other : value;
};

/**
* 5.字符串工具类,去掉字符串左边和右边的空格。
*/
String.prototype.trim = function(){
    var re = /^\s+|\s+$/g;
    return function(){ return this.replace(re, ""); };
}();

/**
* 6.添加到Number原型中constrain方法,判断当前数字是否在某个范围内,第一个参数表示下限,第二个参数表示上限。
*/
Ext.applyIf(Number.prototype, {
    /**
     * Checks whether or not the current number is within a desired range.  If the number is already within the
     * range it is returned, otherwise the min or max value is returned depending on which side of the range is
     * exceeded.  Note that this method returns the constrained value but does not change the current number.
     * @param {Number} min The minimum number in the range
     * @param {Number} max The maximum number in the range
     * @return {Number} The constrained value if outside the range, otherwise the current value
     */
    constrain : function(min, max){
        return Math.min(Math.max(this, min), max);
    }
});

/**
* 7.添加到Array类原型中的方法。
*
* 第一个方法判断特定对象是否在当前数组中,如果在,返回索引值;不在,返回-1.
*
* 第二个方法删除当前数组中的特定对象。返回变化后的数组;如果对象不在,什么也不做。
*/
Ext.applyIf(Array.prototype, {
    /**
     * Checks whether or not the specified object exists in the array.
     * @param {Object} o The object to check for
     * @return {Number} The index of o in the array (or -1 if it is not found)
     */
    indexOf : function(o){
       for (var i = 0, len = this.length; i < len; i++){
      if(this[i] == o) return i;
       }
   return -1;
    },

    /**
     * Removes the specified object from the array.  If the object is not found nothing happens.
     * @param {Object} o The object to remove
     * @return {Array} this array
     */
    remove : function(o){
       var index = this.indexOf(o);
       if(index != -1){
           this.splice(index, 1);
       }
       return this;
    }
});

/**
* 8.添加到Date类原型中的方法getElapsed,返回特定时间与当前时间之间的毫秒数,结果是非负值。
* @param {} date
* @return {}
*/
Date.prototype.getElapsed = function(date) {
return Math.abs((date || new Date()).getTime()-this.getTime());
};

/**
* 9.源码中L42到L634,定义了一个匿名函数并执行,定义了Ext类的公共属性和方法。
*/

//覆盖方法,第一个参数表示原类,第二个参数是覆盖对象,把覆盖对象中的每一个属性赋值给原类的原型中。保证原类的所有实例都具有这些覆盖属性。
override = function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;
                for(var method in overrides){
                    p[method] = overrides[method];
                }
            }
        }

//继承方法,
extend = function(){
            // inline overrides
            var io = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            var oc = Object.prototype.constructor;
           
            return function(sb, sp, overrides){
                if(typeof sp == 'object'){
                    overrides = sp;
                    sp = sb;
                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
                }
                var F = function(){}, sbp, spp = sp.prototype;
                F.prototype = spp;
                sbp = sb.prototype = new F();
                sbp.constructor=sb;
                sb.superclass=spp;
                if(spp.constructor == oc){
                    spp.constructor=sp;
                }
                sb.override = function(o){
                    Ext.override(sb, o);
                };
                sbp.override = io;
                Ext.override(sb, overrides);
                sb.extend = function(o){Ext.extend(sb, o);};
                return sb;
            };
        }()
分享到:
评论

相关推荐

    spketdwcs-ext-2.1.mxp

    spketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-ext-2.1.mxpspketdwcs-...

    EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档

    EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档EXT.JS_文档...

    Ext.js教程和Ext.js API

    Ext.js 是一个强大的JavaScript库,专门用于构建富客户端的Web应用程序。它提供了丰富的用户界面组件和数据绑定功能,使得开发者可以构建出具有桌面应用级别的交互式网页应用。本教程和API文档聚焦于Ext.js 3.0版本...

    Ext.js 6 示例学习

    Ext.js 是一个强大的JavaScript库,专门用于构建富客户端的Web应用程序。它提供了丰富的用户界面组件和数据绑定机制,使得开发者可以构建出具有桌面应用级别的交互式网页应用。本压缩包包含两个PDF文档,分别是“Ext...

    extjs-Ext.ux.form.LovCombo下拉框

    这些文件可以帮助开发者理解并应用`Ext.ux.form.LovCombo`,通过查看源码学习如何初始化、配置以及处理相关事件。 综上所述,`Ext.ux.form.LovCombo`是EXTJS中用于创建具有多选功能和良好浏览器兼容性的下拉框组件...

    ext JS 源码和学习资料

    一、EXT JS 源码分析 EXT JS 的源码结构清晰,包括核心库、组件、布局、数据管理、表单元素等模块。通过阅读源码,开发者可以了解到EXT JS如何实现组件化、事件处理、数据绑定等功能,进一步优化自己的代码结构和...

    ext.js——打印

    打印功能 ext.js,打印功能 ext.js,打印功能 ext.js,打印功能 ext.js,打印功能 ext.js

    Ext.JS.4.First.Look_第1版__._Ext.JS.4.First.Look_.Loiane.Groner.文字版

    ### Ext.JS 4.0 第一印象:新特性与迁移指南 #### 一、书籍简介 本书《Ext.JS 4.0 第一印象》由 Loiane Groner 撰写,是一本针对 Ext.JS 4.0 的实用指南。书中详细介绍了 Ext.JS 4.0 的新特性,并提供了从 Ext.JS ...

    Ext.ux.SwfUploadPanel.js

    `Ext.ux.SwfUploadPanel.js`是这样一个基于ExtJS和SwfUpload技术的插件,它实现了多文件上传的功能。这篇文章将深入探讨这个插件的工作原理、主要特点以及如何在实际项目中应用。 首先,`ExtJS`(全称为EXT ...

    Ext.get与Ext.fly的区别

    在Ext JS框架中,`Ext.get`和`Ext.fly`是两个非常重要的方法,它们主要用于操作DOM元素。理解这两个方法之间的区别以及如何使用它们对于开发高质量、高效率的应用程序至关重要。 #### 1. Ext.get **定义**:`Ext....

    ext.js拖动3.4版本插件

    Ext JS 是一个强大的JavaScript应用程序框架,它提供了丰富的用户界面组件和功能,用于构建富客户端Web应用。在3.4版本中,它包含了对拖放功能的良好支持,这使得开发者能够轻松实现各种元素的动态交互,比如在布局...

    ext.js监听事件

    ext封装的太死板,里面有常用到的15个ext.js触发事件和监听事件,对ext了解的不是特别深入,大部分都是经常碰到的

    ext.js3 源码

    ext-all.js\ext-all-debug.js\adapter\examples\pkgs\resources\src

    ext.js 4.2 demo+文件

    官方文件加示例,ext.js 4.2版本,后面就是凑字数了后面就是凑字数了

    Ext.Ajax.request2.x实现同步请求

    `ext-basex.js`是EXTJS的基础组件文件,其中包含了Ajax请求的相关实现。在旧版本中,可能需要对请求选项进行更详细的配置来适应不同的浏览器环境。 在EXTJS中,`Ext.Ajax`对象提供了丰富的配置项和方法,如`params`...

    EXT.js4.2实战

    EXT.js4.2是EXT JS框架的第4.2版本,是一个完整的前端开源JavaScript框架,用于开发基于Web的交互式应用程序。该框架提供了丰富的组件库,允许开发者创建具有丰富界面的单页应用程序(SPA)。EXT.js4.2不仅包括UI...

    Ext.Ajax.request跨域

    打开并分析这个文件可以帮助我们更好地理解实际项目中跨域的实现方式。 5. 源码与工具: 标签"源码 工具"提示这个话题可能涉及到具体的代码实现和一些辅助工具。在实际开发中,开发者可能需要用到如Postman这样的...

    深入浅出Ext.JS.徐会生等

    《深入浅出Ext.JS》是由徐会生等人编著的一本关于Ext.JS的权威技术书籍,旨在帮助读者全面理解和掌握这一强大的JavaScript框架。Ext.JS是一个用于构建富客户端Web应用的开源库,它提供了丰富的组件库和强大的数据...

    Ext.Store的获取方法

    在Ext.js中,`Ext.Store`是用来管理数据的类,它通常与各种UI组件(如Grid、ComboBox等)关联,用于存储和检索数据。然而,获取`Ext.Store`的方式并不像获取其他Ext组件那样直接,因为Store并不是一个具有可视界面的...

    Ext.data.Store的基本用法

    ### Ext.data.Store的基本用法详解 #### 一、Ext.data.Store简介 `Ext.data.Store`是ExtJS框架中用于管理数据的核心组件之一。它主要负责数据的存储、加载、更新等操作,并且提供了多种方法来方便地处理这些数据。...

Global site tag (gtag.js) - Google Analytics