ExtJs 架构分析.doc_第1页
ExtJs 架构分析.doc_第2页
ExtJs 架构分析.doc_第3页
ExtJs 架构分析.doc_第4页
ExtJs 架构分析.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

理解Ext.util.Event由于Ext2.0中所有的组件都是由Observable继承而来,理解Ext就需要先从Ext.util.Observable说起,而 Observable是对Event对象进行管理,从而理解Observable必须首先从Ext.util.Event说起。 Ext.util.Event是一个封装的非常精致的对象,但和你想象的不同,Event同任何的HTML DOM元素没有任何的关系(尽管Ext是处理HTML元素的),实际上,它是一个通用的事件及其事件的处理的对象。 也许有朋友要问,HTML Element本身已经支持了事件,为什么还要再重新设计一套Event机制呢?其实,基本上所有的javascript框架都会实现自己的Event机制,原因很多,但是至少有一点:HTML元素对于事件的处理是通过简单的单一绑定实现,也就是说,如果不进行任何的封装,你的事件只能唯一的绑定到一个事件处理句柄,举个例子: var e=document.getElementById(test); e.onclick=function()alert(handle1); e.onclick=function()alert(handle2); 运行的结果你回发现,只会弹出一个handle2的alert框,因为第一个事件已经被第二个事件重载了。而使用Ext框架,你可以放心的解决这个问题,同一个事件可以依次被绑定到多个事件处理句柄上。 Ext.util.Event对象构建器需要传入两个对象:obj(处理事件的缺省对象),name(事件名称)。在构建Event对象时,Event对象会同时构建一个事件的处理函数的数组:listeners,通过这个数组实现了一个事件的多个事件句柄函数的处理。 Ext.util.Event = function(obj, name) = name; this.obj = obj; this.listeners = ; ; 通过Event的fire方法就可以依次触发该数组中的处理函数。实际上,fire方法在遍历listeners数组中的处理函数过程中,只要处理函数的返回值为false,则不再继续运行后续的处理函数。所以,可以通过检查fire方法的返回值得知事件处理函数是否完全被运行。 fire : function() var ls = this.listeners, scope, len = ls.length; if(len 0) this.firing = true;/通过firing可以保证多个事件处理函数不会并发运行 var args = Atotype.slice.call(arguments, 0);/slice方法可以有效的进行数组的克隆 for(var i = 0; i 1) for(var i = 0; i len; i+) this.add(a); return; /this.applyDefaults(comp)方法对元素设置了缺省属性,注意到此时为止,还没有生成相应的组件,现在的item对象依然还是一个简单的json对象。lookupComponent方法则会生成元素组件 var c = this.lookupComponent(this.applyDefaults(comp); var pos = this.items.length; if(this.fireEvent(beforeadd, this, c, pos) != false & this.onBeforeAdd(c) != false) this.items.add(c); /把每个子元素的ownerCt设置成Container自己 c.ownerCt = this; /触发add事件 this.fireEvent(add, this, c, pos); return c; , 让我们看一下lookupComponent方法的实现: lookupComponent : function(comp) if(typeof comp = string) 如果传入的是字符串,进行查找 return Ext.ComponentMgr.get(comp); else if(!comp.events) /如果是对象,但不是继承自Observable的对象(在这里,即不是Widget组件对象),则新建一个对象,这就是我们前面讨论的情况,传入的是配置数组。 return this.createComponent(comp); return comp; , 魔术的答案在这里,createComponent 方法的实现: createComponent : function(config) /this.defaultType是panel,Container缺省实现是根据传入的json对象创建相应的panel return Ext.ComponentMgr.create(config, this.defaultType); , 而ComponentMgr的create方法的实现也很简单: create : function(config, defaultType) return new typesconfig.xtype | defaultType(config); 最终,秘密揭晓,Container的缺省实现将根据传入的items数组中的每个item的xtype属性进行子元素的创建。如果在item中未指定xtype,则根据配置创建panel. Ext.Container除了通过add()方法,还提供了insert(),remove()等方法实现了对items的维护。在item中的每个元素被加入items之前,都调用beforeAdd方法,如果返回值为true,则该元素元素被设置缺省属性(通过applyDefaults方法),并吧ownerCt属性赋为container,然后加入items,并触发add事件。 Container还提供了两个很有用的方法:bubble和cascade。 bubble方法实现了一个方法在父容器中的递归调用,当然,只要方法在任何一个父容器中返回false,则调用被终止; cascade方法则实现了方法在容器的子元素中被调用; 需要指出的是,如果未设置任何layout,则container返回ContainerLayout: getLayout : function() if(!this.layout) var layout = new Ext.layout.ContainerLayout(this.layoutConfig); this.setLayout(layout); return this.layout; 让我们再看一下对于layout的管理,通过render方法,Container设置了layout对象并调用了doLayout方法: render : function() Ext.Container.superclass.render.apply(this, arguments); if(this.layout) if(typeof this.layout = string) this.layout = new Ext.Container.LAYOUTSthis.layout.toLowerCase()(this.layoutConfig); this.setLayout(this.layout); if(this.activeItem != undefined) var item = this.activeItem; delete this.activeItem; this.layout.setActiveItem(item); return; if(!this.ownerCt) this.doLayout(); if(this.monitorResize = true) Ext.EventManager.onWindowResize(this.doLayout, this); doLayout方法则调用自己的layout对象的layout方法并遍历items中的元素,逐个调用layout方法: if(this.rendered & this.layout) this.layout.layout(); if(this.items) var cs = this.items.items; for(var i = 0, len = cs.length; i len; i+) var c = cs; if(c.doLayout) c.doLayout(); Layout初识:ContainerLayout如果学习了Container,你回发现,在Ext2.0中,Container和Layout的关系是密不可分的。任何Container都需要在render方法中使用layout对象进行布局。 让我们先看一下所有layout的父类:ContainerLayout。 实际上,对容器及其item的渲染都是在layout对象的layout方法中实现的。而layout方法是在resize事件中触发的,基于性能的考虑,可以通过配置bufferResize属性实现延迟layout: onResize: function() if(this.container.collapsed) return; var b = this.container.bufferResize; if(b) if(!this.resizeTask) this.resizeTask = new Ext.util.DelayedTask(this.layout, this); this.resizeBuffer = typeof b = number ? b : 100; this.resizeTask.delay(this.resizeBuffer); else this.layout(); lyout方法会遍历所有的Container子元素并对其进行render: renderItem : function(c, position, target) if(c & !c.rendered) c.render(target, position); if(this.extraCls) var t = c.getPositionEl ? c.getPositionEl() : c; t.addClass(this.extraCls); if (this.renderHidden & c != this.activeItem) c.hide(); else if(c & !this.isValidParent(c, target) if(this.extraCls) c.addClass(this.extraCls); if(typeof position = number) position = target.dom.childNodesposition; target.dom.insertBefore(c.getEl().dom, position | null); if (this.renderHidden & c != this.activeItem) c.hide(); 最简单的layout:AnchorLayoutAnchorLayout是最简单的布局管理其,它只是将元素按照配置的属性在元素容器中进行定位。 让我们看一下它的render方法以理解如果进行布局: onLayout : function(ct, target) Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target); /获取元素的尺寸 var size = this.getAnchorViewSize(ct, target); var w = size.width, h = size.height; if(w 20 | h 20) return; / 获取容器的尺寸 var aw, ah; if(ct.anchorSize) if(typeof ct.anchorSize = number) aw = ct.anchorSize; else aw = ct.anchorSize.width; ah = ct.anchorSize.height; else /根据配置获取容器尺寸 aw = ct.initialConfig.width; ah = ct.initialConfig.height; /遍历元素,并调用元素的setSize方法,继承自boxComponent的setSize方法则触发resize事件从而触发layout方法。 var cs = ct.items.items, len = cs.length, i, c, a, cw, ch; for(i = 0; i len; i+) c = cs; if(c.anchor) a = c.anchorSpec; if(!a) / cache all anchor values var vs = c.anchor.split( ); c.anchorSpec = a = right: this.pars

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论