ExtJS 4组件的生命周期
ExtJS组件的生命周期可以整体上划分为三个部分:初始化、渲染、销毁。生命周期由Ext.Component类控制。
初始化(Initialization)
这一阶段通常执行的很快,因为都是在JavaScript代码内完成的。注意:组件不需要经过渲染阶段即可被销毁。
该阶段整体流程图如下:
各步骤说明如下:
- 应用配置项:在实例化组件的时候,我们可以传递一个配置对象(包含若干配置项),其中包含新组件必要的参数、引用
- 底层(Base)事件注册:Ext.Component类定义了若干核心事件,这些事件在组件的某些行为前、后触发(对应事件名称beforeXxx、afterXxx),这些行为包括:enable/disable、show/hide、render/ destroy、 state restore/state save。其中before事件处理函数如果返回false,则行为被取消,例如,如果beforeshow返回false,那么组件的show行为将不生效,即不显示。通常这些事件都由Ext.Component类本身负责触发
- 分配或者生成组件ID:如果没有指定ID,ExtJS会自动为组件生成
- 构造Pre-initComponent插件:所有在initComponent之前定义的插件被创建,该步骤允许某些插件(例如Grid编辑器)尽早的执行必要的动作
- 执行initComponent:这是最重要的一个扩展点。initComponent方法中会包含很多逻辑,例如:
- 注册子类特有的事件
- 引用数据存储
- 创建子组件
- 在ComponentManager中注册当前组件
- 底层(Base)混入类构造器调用:组件提供两个混入类提供底层功能,Ext.util.Observable为组件提供发布、监听事件的能力;Ext.state.Stateful为组件处理状态相关(state-specific)的事件
- 组件的resize事件作为状态事件(state event)初始化,状态事件用于保存组件的状态
- 初始化插件:如果提供了plugins配置,那么在此调用插件的init方法,并传入当前Component作为其参数。如果由多个插件,按照在配置中声明顺序初始化之
- 启动组件的数据加载器:如果提供了一个loader配置项,则用其创建ComponentLoader,下面是一个例子:
12345678910111213var cmp = Ext.create( 'Ext.Component', {renderTo : Ext.getBody(),tpl : '{firstName} - {lastName}', //HTML内容模板loader : {url : 'userinfo',autoLoad : false, //是否自动加载数据renderer : 'data', //使用data作为渲染器,则自动提供给模板使用params : {userId : 1}}} );cmp.getLoader().load(); - 组件被渲染:如果提供renderTo、applyTo配置项,那么立即开始渲染阶段;否则,组件等待其render()方法被其容器或者被用户代码调用,不作为其他容器子组件的组件,必须手动渲染,例如:
1someComponent.render('someDivId');
渲染(Render)
这一阶段用户将得到组件的视角反馈。如果初始化阶段出现任何问题,组件将渲染错误或者根本不渲染。
该阶段整体流程图如下:
各步骤说明如下:
- 触发beforerender事件:组件发布该事件,并检查所有监听器函数的返回值,如果任一返回值为false,停止渲染
- 组件对应的DOM元素被缓存:如果指定了el配置项,那么使用一个Ext.Element包围el对应的元素
- 浮动组件注册:如果组件被配置为floating,则在WindowManager中注册自身,以便启用Z-Index、焦点管理。这一步骤对Window、Menu等组件比较重要
- 设置组件所在的容器:
- 如果指定了renderTo配置项,则在目标元素下添加单个DIV,并在此DIV中渲染当前组件
- 如果指定了applyTo配置项,则目标元素直接作为组件的容器,目标元素将被组件完全管理
- 调用onRender:这是一个关键的步骤,组件的所有DOM元素被插入到文档中,并且渲染到屏幕上。每个组件子类应当首先调用其父类的onRender方法,然后再执行子类特有的逻辑
- 可见性模式(Visibility mode)被配置:通过组件的hideMode配置来设置,可以是display、visibility、offsets
- 初始化overCls:如果提供了overCls配置项,则组件使其元素在mouseover、mouseout事件发生时添加、去除对应的CSS样式
- 触发render事件:在此刻,所有必须的元素已经插入到文档,并且应用了样式
- 初始化组件的内容:如果提供了contentEl、html、tpl或者data配置项,则在组件对应的DIV中渲染HTML代码
- 调用afterRender:该方法会被render自动调用,这是一个重要的模板方法包括以下职责:
- 配置组件的尺寸、对齐、位置,并且为HTML内容添加一些样式
- 如果组件为Resizable,则执行Resizable类的初始化
- 如果组件为draggable,则执行相应的逻辑使其可拖拽
- 如果配置了autoScroll,则设置组件的滚动条
- 触发afterrender事件:通知监听器,所有关键的渲染操作都完成了,该事件是很好的操控组件DOM的时机
- 挂钩afterRenderEvents
- 组件的元素可以支持聚焦
- 如果组件被配置为hidden:true,则调用其hide()方法
- 如果组件被配置为disabled:true,则调用其disable()方法
销毁(Destruction)
销毁阶段包含重要的资源清理动作,例如:移出组件(包括子组件)的DOM元素、从ComponentManager注销组件、注销事件监听器。
该阶段整体流程图如下:
各步骤说明如下:
- 触发beforedestroy事件:如果任何一个监听器返回false,则取消组件的销毁
- 调用beforeDestroy:组件的destroy()方法首先调用该模板方法,在这里可以完成非组件成员的销毁
- 如果当前组件是floating,则从FloatingManager中解除自身的注册
- 从父容器中移出当前组件
- 调用onDestroy,该模板方法包括以下职责:
- 销毁所有配置的drag-and-drop代理
- 销毁配置的Resizer
- 如果组件监视浏览器的resize事件,则解除注册该监听器
- 销毁配置的ComponentLayout、loadMask、任何浮动子组件
- 销毁注册的插件:遍历并调用其destroy()方法
- 如果组件已经渲染,则清理Element对象(从文档中删除DOM节点)、Element的事件监听器
- 触发destroy事件:此时组件已经不存在于文档
- 从ComponentManager解除注册
- 销毁Ext.state.Stateful混入类,并且解除任何状态相关(state-specific)的组件事件
- 销毁组件的事件监听器
Leave a Reply