`

ExtJs源码分析与学习—ExtJs核心代码(三)

阅读更多

Ext为javascript的一些对象进行了扩展,主要有String、Array和Function,以下只介绍Ext.js中提到的方法,其他的后续再介绍

 

Ext为String扩展了方法 format,该方法为String的静态方法(类方法),可以把字符串中特殊写法({0},{1})用指定的变量替换

 

//定义带标记的字符串,并用传入的字符替换标记。每个标记必须是唯一的,而且必须要像{0},{1}...{n}
 //这样地自增长。
 //var cls = 'my-class', text = 'Some text';
 //var s = String.format('{0} '  '{1}', cls, text);
    //s现在是字符串:s now contains the string: 'my-class'   'Some text'

    format : function(format){
        var args = Ext.toArray(arguments, 1);
        return format.replace(/\{(\d+)\}/g, function(m, i){
            return args[i];
        });
    }

 
 Ext为Array扩展了方法 indexOf 和remove,这两个方法分别实现了索引和根据子元素删除对应的该元素

Ext.applyIf(Array.prototype, {
    /**
     * Checks whether or not the specified object exists in the array.
     * @param {Object} o The object to check for
     * @param {Number} from (Optional) The index at which to begin the search
     * @return {Number} The index of o in the array (or -1 if it is not found)
     */
    indexOf : function(o, from){
        var len = this.length;
        from = from || 0;
        from += (from < 0) ? len : 0;
        for (; from < len; ++from){
            if(this[from] === o){
                return from;
            }
        }
        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;
    }
});

 

编者在实际开发中经常会用到以下两个方法,也很实用

 

/**
  * 数组插入元素
  * @param {} index 插入位置
  * @param {} o 插入元素
  * @return {}
  */
 insert : function (index,o){
  if(index <= 0){
            return this.unshift(o);//插入到首元素
        }
        if(index >= this.length){
            return this.push(o);//插入到末元素
        }
        var sub = this.slice(index, this.length);
        this.length = index;
        this.push(o);
        for(var i = 0; i < sub.length; i++){
         this.push(sub[i]);
        }
        return this;
 },
 
 /**
  * 删除数组中指定的元素
  * @param {} index
  * @return {}
  */
 removeAt : function(index){
        if(index != -1){
            this.splice(index, 1);
        }
        return this;
    }

 

以下扩展String方法也很有用

Ext.applyIf(String,{
 
 /**
  * 把驼峰格式的字符串转换为-格式
  * alert(humpToConnector('aaaBbbCcc','-')); //return aaa-bbb-ccc
  * @param {} str
  * @param {} conj
  * @return {}
  */
    humpToConnector : function(str, conj){
  //str = !str ? str : String(str);
  var index = str.search(/[A-Z]/);
  if (index >= 0) {
   var c = str.charAt(index);
   return String.humpToConnector(str.substring(0, index) + conj
       + c.toLowerCase() + str.substring(index + 1), conj);
  } else {
   return str;
  }
 }
});

 

Ext对Function的扩展

 

createInterceptor方法

createInterceptor : function(fcn, scope){
        var method = this;
        return !Ext.isFunction(fcn) ?
                this :
                function() {
                    var me = this,
                        args = arguments;
                    fcn.target = me;
                    fcn.method = method;
                    return (fcn.apply(scope || me || window, args) !== false) ?
                            method.apply(me || window, args) :
                            null;
                };
    },
 

该方法实现了类似拦截器的功能,传递的参数fcn在原函数之前调用。如果fcn的返回值为false,则原函数不会被调用。即函数fcn拦截时,如果fcn返回false,将被拦截,true则执行。以下说明方法中的部分语句。

 

var method = this,因为是给Function.prototype扩展,因此其prototype上挂的所有的函数,函数内的this都是Function,即函数自身。看下面例子

Function.prototype.test = function(){
	alert(this);
};
function fn(){return 'test';}
fn.test();

  结果输出

function fn() {

    return "test";

}

即this就是fn函数本身

 

!Ext.isFunction(fcn),这个条件表明如果所传参数fcn不是一个function,那么将直接返回this,this即函数自身。或者说这时没有进行任何拦截,原样返回了该函数自身。

 

当fcn为一个function时,将执行 “:”后的分支,此时给fcn添加了两个属性target,method。target是me,me是this。

此时的this是什么呢?多数情况下是window,但整个function如果作为对象属性存在时,this则是该对象。谁调用了createInterceptor,method就是谁。如:

 

function oldFn(){
	alert('test');
}
function ret(){
	return false;
}
var newFn = oldFn.createInterceptor(ret);
newFn();

oldFn继承了createInterceptor方法,且调用了它,参数是ret。这时createInterceptor内部的method, fcn.method就是oldFn;me,fcn.target则为window对象。改成如下,me,fcn.target则为obj了

 

function oldFn(){
	alert('test');
}
function ret(){
	return false;
}
var obj = {name:'jack'};
obj.method = oldFn.createInterceptor(ret);
obj.method();

  (fcn.apply(scope || me || window, args) !== false),所传参数fcn被执行,执行上下文优先是scope,其次是me,最后是window。返回结果不等于false才执行method。method执行上下文先为me,me不存在则是window。

 

现把官方例子贴出来

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"

 

该例子在createInterceptor中  fcn.apply(scope || me || window, args) 相当于直接执行

function(name){

    return name == 'Brian';

}

只是将函数绑定到另外一个对象上(scope || me || window)去运行

method 实际为sayHi

 

createCallback方法

 

//创建一个回调函数,该回调传递参数的形式为:arguments[0],...
    createCallback : function(/*args...*/){
        // make args available, in function below
        var args = arguments,
            method = this;
        return function() {
            return method.apply(window, args);
        };
    },
 

这个方法非常有用,实现简单。返回一个新函数,新函数内执行method,会把外面的参数给传进来。
初学者经常 纠结于给事件handler传参数  。createCallback 解决了给DOM事件handler(监听器)传参问题。
createCallback 不仅用在DOM事件handler上你完全可以自定义事件,设计一套属于自己的 观察者模式  API。即每个类有自己的事件,如 LTMaps  ,除了拥有属性,方法还有许多事件,如移动地图(move),缩放地图(zoom)。Ext的众多UI组件也都是这种模式,Ext.Panel 具有afterlayout,close等事件。

在给这些事件添加hanlder,又想传参或许也会用到 createCallback。

 

 

createDelegate 方法

 

//创建一个委派对象(就是回调),该对象的作用域指向obj。对于任何函数来说都是可以直接调用的。
    //obj : Object (可选的) 自定义的作用域对象。(optional) The object for which the scope is set 
    //args : Array (可选的) 覆盖该次调用的参数列表。(默认为该函数的arguments)。(optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) 
    //appendArgs : Boolean/Number(可选的) 如果该参数为true,将args加载到该函数的后面,如果该参数为数字类型,则args将插入到所指定的位置。
    //顺便说一下Array.prototype.slice(start,end)的用法,返回选定的所有元素的数组,start,end可选参数,默认为返回所有元素
    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 (Ext.isNumber(appendArgs)){
                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);
        };
    },

 

createDelegate 比 createCallback 更强大,除了能解决回调函数传参问题。还能控制:
1, 自定义参数是否覆盖默认参数(如 DOM事件对象  作为handler第一个参数)
2, 自定义参数的位置

内部实现:取自身(var method=this),返回一个新function,该function调用自身(method.apply),同时指定上下文(obj||window)及参数(callArgs)。就这么简单,细节之处在于对参数的控制。

1,只传obj和args时将覆盖回调函数默认参数(DOM事件对象)

<a href="#" id="aa">SINA</a>
<script type="text/javascript">
	var aa = document.getElementById('aa');
	function sayName(name){
		alert('hello, ' + name);
	}
	var sayName2 = sayName.createDelegate(aa,['jack']);
	aa.onclick = sayName2;
</script>

 2,三个参数都传,appendArgs为true时,默认参数(DOM事件对象)位置不变(第一个),自定义参数args在最后

<a href="#" id="aa">SINA</a>
<script type="text/javascript">
	var aa = document.getElementById('aa');
	function sayName(){		
		alert('实际参数长度:' + arguments.length);
		alert('hello, ' + arguments[0]);
		alert('hi, ' + arguments[1]);
	}
	var sayName2 = sayName.createDelegate(aa,['jack'],true);
	aa.onclick = sayName2;
</script>

 3, 三个参数都传,appendArgs为数字时将指定自定义参数的位置

<a href="#" id="aa">SINA</a>
<script type="text/javascript">
	var aa = document.getElementById('aa');
	function sayName(name){		
		alert('实际参数长度:' + arguments.length);
		alert('hello, ' + arguments[0]);
		alert('hi, '+ arguments[1]);
		alert('hi, '+ arguments[2]);
	}
	var sayName2 = sayName.createDelegate(aa,['jack','lily'],0);
	aa.onclick = sayName2;
</script>

 

defer 方法

 

/**
     * 延迟调用该函数
     * @param {} millis 延迟时间,以毫秒为单位(如果是0则立即执行)
     * @param {} obj (可选的) fcn的作用域(默认指向原函数或window)
     * @param {} args (可选的) 覆盖原函数的参数列表(默认为该函数的arguments)
     * @param {} appendArgs (可选的)如果该参数为true,将args加载到该函数的后面,如果该参数为数字类型,则args将插入到所指定的位置
     * @return {Number}
     */
    defer : function(millis, obj, args, appendArgs){
        var fn = this.createDelegate(obj, args, appendArgs);
        if(millis > 0){
            return setTimeout(fn, millis);
        }
        fn();
        return 0;
    }
 

 

 

 

  • Ext.rar (12.4 KB)
  • 下载次数: 13
分享到:
评论
1 楼 dengweikobe 2012-07-30  
赞一个!   

相关推荐

    ExtJs源码分析与学习—ExtJs核心代码(一)

    NULL 博文链接:https://linder0209.iteye.com/blog/865372

    Extjs源码分析与开发实例宝典

    《Extjs源码分析与开发实例宝典》全面介绍了ExtJS的技术细节和开发实践,是学习和掌握ExtJS不可或缺的资源。通过对本书的深入阅读,开发者不仅可以理解ExtJS的工作原理,还能学会如何运用ExtJS构建高效、美观的Web...

    资料:包括extjs2.0源码

    6. **图表组件**:EXTJS 2.0内置了各种图表类型,如柱状图、饼图、线图等,适用于数据可视化需求,源码分析有助于定制高级图表功能。 7. **Ajax交互**:EXTJS 2.0通过Ajax技术实现与服务器的异步通信,提供了强大的...

    Django整合Extjs源码

    **Django整合ExtJS源码解析** 在Web开发领域,Django作为一个强大的Python Web框架,以其高效、安全和可扩展性而备受青睐。与此同时,ExtJS是一个JavaScript库,用于构建富客户端应用程序,提供了丰富的组件和数据...

    ExtJS 3.4 源码包

    1. **ExtJS核心概念** - **组件模型**:ExtJS基于组件化设计,每个UI元素都是一个可复用的组件,如窗口(Window)、表格(Grid)、表单(Form)等。 - **布局管理**:ExtJS提供多种布局方式,如Fit布局、Border...

    ExtJs 实例+ExtJs中文教程(学习extjs必备)

    最后,结合源码分析,提升你的编程水平,能够更好地应对复杂的应用需求。 总之,ExtJs是一个强大的JavaScript框架,通过学习提供的实例和中文教程,结合具体的代码实践,你将能够开发出功能丰富、用户体验优秀的Web...

    ExtJS源码分析与开发实例宝典--书中代码

    核心技术部分深入讲解Ext JS的核心基础知识,包括JS原生对象的扩展、事件机制、 模板模型、数据模型,包括一个机制、两个模型及六个扩展。基于元素的开发部分讲解了在DOM元素基 础上扩展的Ext JS元素,包括元素操作...

    Extjs 4.0 源码说明文档入门手册 和示例

    源码分析: 在`ext-4.0.0`目录中,你将找到ExtJS 4.0的核心源代码。这些文件主要分为以下几个部分: 1. `src`目录:这是ExtJS的核心源码存放处,包含了所有组件、类和工具函数。每个主要的组件或功能都有自己的子...

    掏钱学ExtJs完全版附全部源码- 康海涛

    康海涛的"掏钱学ExtJs完全版"可能是一份全面的学习资料,涵盖了ExtJs的基础到高级应用,包括源码分析,旨在帮助学习者深入理解和掌握这一技术。 首先,ExtJs的核心是其组件模型。它提供了大量的预定义组件,如表格...

    extjs grid.panel 项目 源码

    10. **最佳实践**:源码分析也能让我们学习到ExtJS开发的最佳实践,例如如何有效地组织代码,如何优化数据加载,以及如何保持组件的可维护性。 通过深入研究这个"extjs grid.panel 项目 源码",我们可以提升对ExtJS...

    EXTJS部分中文源码

    通过分析源码,开发者可以学习到如何自定义组件,优化性能,甚至开发自己的EXTJS插件。此外,熟悉EXTJS的源码也有助于解决在实际项目中遇到的问题,因为有时官方文档可能不包含所有细节,而源码往往能给出最准确的...

    extJS3.1源码及demo

    在"extJS3.1源码及demo"这个资源中,你将找到ExtJS 3.1.0的完整源代码和相关的示例。源码的分析对于深入理解框架的工作原理至关重要,特别是对于那些想要进行定制化开发或者优化性能的开发者来说。源码包含了各种...

    基于ExtJS5的后台管理系统案例 - 源码

    ExtJS5是一款强大的JavaScript框架,主要用于构建富客户端的Web应用程序,尤其在开发复杂的后台管理系统时,它的优势尤为显著。...案例中的源码分析和实践将加深对框架的理解,为后续的Web开发工作打下坚实基础。

    ExtJs源码以及文档相关资料

    这个资料包“ExtJs源码以及文档相关资料”显然包含了ExtJS 4.1.1版本的源代码和相关的文档,这对于深入理解ExtJS的工作原理和学习如何使用它是极为宝贵的资源。 首先,ExtJS 4.1.1是该框架的一个稳定版本,发布于...

    ExtJS4.0-WEB开发项目源代码

    在“ExtJS4.0-WEB开发项目源代码”这个资源中,你将有机会接触到基于ExtJS 4.0版本的项目实例,这对于学习和理解ExtJS的应用开发是非常有价值的。 首先,让我们深入了解ExtJS 4.0的关键特性: 1. **组件化**:...

    Ajax框架ExtJS3.0源代码

    源码分析有助于提升对JavaScript和Web开发的理解,对于前端开发者来说,是一份宝贵的参考资料。 1. **组件系统**:ExtJS3.0的组件模型是其核心部分,包括窗口(Window)、表格(Grid)、面板(Panel)、按钮...

    进销存php源码(extjs)

    进销存系统是一种广泛应用于企业运营中的...开发者可以通过理解和学习这套源码,掌握企业级应用开发的方法,提高自己的技能。同时,对于企业来说,这样的开源系统能够降低信息化成本,快速搭建适合自身业务的管理系统。

    深入浅出ExtJS随书源码--EXTJS2.0

    "深入浅出ExtJS随书源码--EXTJS2.0"是针对ExtJS 2.0版本的学习资源,通常与一本相关书籍配套,帮助读者通过实际代码加深对ExtJS的理解。 源码分析: 1. **组件系统**:ExtJS的核心是其组件模型,其中包括各种可...

    asp.net与extjs开发点卡在线销售系统完整源码

    《ASP.NET与EXTJS开发的点卡在线销售系统详解》 在互联网技术高速发展的今天,电子支付和在线交易已经成为日常生活的一部分。点卡作为一种便捷的预付费方式,广泛应用于游戏、软件激活、网络服务等多个领域。本文将...

Global site tag (gtag.js) - Google Analytics