初学Ext UI组件总结及(一)-- >读Ext.Component源码学习笔记
2012-02-13 23:11
246 查看
为了可以缓解审美疲劳,写出自己的Ext UI组件,加油。
错误之处,请大家指出。
Ext.Component是所有UI组件的顶层类,它继承了Observable,以支持高级语义事件。
Ext的UI组件的生命周期,粗略可分为,初始化组件-->渲染组件-->销毁组件
Ext.Component有点“模板模式”的味道,它不能“布局”也不能“show”出来,它只是定义了所有UI组件的“生老病死”和实现了一些通用的逻辑,然而每个组件的初始化过程渲染过程都不尽相同,所以具体的实现推迟到不同的子类中实现。
源码片段一(构造函数中)
错误之处,请大家指出。
Ext.Component是所有UI组件的顶层类,它继承了Observable,以支持高级语义事件。
Ext的UI组件的生命周期,粗略可分为,初始化组件-->渲染组件-->销毁组件
Ext.Component有点“模板模式”的味道,它不能“布局”也不能“show”出来,它只是定义了所有UI组件的“生老病死”和实现了一些通用的逻辑,然而每个组件的初始化过程渲染过程都不尽相同,所以具体的实现推迟到不同的子类中实现。
源码片段一(构造函数中)
config构造参数的 config = config || {}; //传特殊参数的处理 if(config.initialConfig){ if(config.isAction){ // actions this.baseAction = config; } config = config.initialConfig;
//容错处理,如果传入的是dom或者是Ext.Element及字符串,那么就根据它生成一个 //配置项 }else if(config.tagName || config.dom || Ext.isString(config)){ config = {applyTo: config, id: config.id || config}; } this.initialConfig = config; //拷贝配置项到"this" Ext.apply(this, config);
//添加一些语义事件,可以想一下,此层应该对应实现什么事件 this.addEvents{...} //下面二行,对此UI实例进行注册,以便可以借助Ext.ComponentMgr快捷的超找出 //此UI组件 this.getId(); Ext.ComponentMgr.register(this); //调用父类的构造参数 Ext.Component.superclass.constructor.call(this); //初始化组件,这个是模板方法,留空,交给子类重写 this.initComponent(); //这个是插件机制,比较有意思,理解还很浅,有一个“接口”,插件需要实现init()方 法 if(this.plugins){ if(Ext.isArray(this.plugins)){ for(var i = 0, len = this.plugins.length; i < len; i++){ this.plugins[i] = this.initPlugin(this.plugins[i]); } }else{ this.plugins = this.initPlugin(this.plugins); } } //状态管理 if(this.stateful !== false){ this.initState(); }
//渲染,applyTo和renderTo的区别在于插入DOM的位置,但最终依旧是依靠render函数渲染 if(this.applyTo){ this.applyToMarkup(this.applyTo); delete this.applyTo; }else if(this.renderTo){ this.render(this.renderTo); delete this.renderTo; }
Ext.extend(Ext.Component, Ext.util.Observable, {..}); //...中,添加的重要实例方法如下 //源码注释:this is double processing, however it allows people to be able to do initComponent : function(){ //在UI继承树顶层的Ext.Component只是绑定了监听器 if(this.listeners){ this.on(this.listeners); delete this.listeners; } this.enableBubble(this.bubbleEvents); }, //渲染过程,精华所在 render : function(container, position){ //触发了beforerender事件,不为false才继续渲染,可以写此监听让其返回false阻止其渲染 if(!this.rendered && this.fireEvent('beforerender', this) !== false){ //找到容纳元素的容器 if(!container && this.el){ this.el = Ext.get(this.el); container = this.el.dom.parentNode; this.allowDomMove = false; } //很巧妙的一步,把包裹整个UI的最外层,包装成Ext.Element元素,比便可以使用Element的动画,拖拽,及其他工具函数 this.container = Ext.get(container); //添加容器的层叠样式 if(this.ctCls){ this.container.addClass(this.ctCls); } this.rendered = true; if(position !== undefined){ if(Ext.isNumber(position)){ position = this.container.dom.childNodes[position]; }else{ position = Ext.getDom(position); } } //子类中需要根据如何渲染重写此方法 this.onRender(this.container, position || null); if(this.autoShow){ this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]); } if(this.cls){ this.el.addClass(this.cls); delete this.cls; } if(this.style){ this.el.applyStyles(this.style); delete this.style; } if(this.overCls){ this.el.addClassOnOver(this.overCls); } //触发render事件 this.fireEvent('render', this); var contentTarget = this.getContentTarget(); //根据配置项html,或者tpl'(模板)插入dom内容 if (this.html){ contentTarget.update(Ext.DomHelper.markup(this.html)); delete this.html; } if (this.contentEl){ var ce = Ext.getDom(this.contentEl); Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); contentTarget.appendChild(ce); } if (this.tpl) { if (!this.tpl.compile) { this.tpl = new Ext.XTemplate(this.tpl); } if (this.data) { this.tpl[this.tplWriteMode](contentTarget, this.data); delete this.data; } } //渲染完毕 //调用afterReader函数 this.afterRender(this.container); if(this.hidden){ // call this so we don't fire initial hide events. this.doHide(); } if(this.disabled){ // pass silent so the event doesn't fire the first time. this.disable(true); } if(this.stateful !== false){ this.initStateEvents(); } this.fireEvent('afterrender', this); } return this; },
//真正干渲染工作的方法,需要根据子类重写 onRender : function(ct, position){ if(!this.el && this.autoEl){ if(Ext.isString(this.autoEl)){ this.el = document.createElement(this.autoEl); }else{ var div = document.createElement('div'); Ext.DomHelper.overwrite(div, this.autoEl); this.el = div.firstChild; } if (!this.el.id) { this.el.id = this.getId(); } } if(this.el){ this.el = Ext.get(this.el); if(this.allowDomMove !== false){ ct.dom.insertBefore(this.el.dom, position); if (div) { Ext.removeNode(div); div = null; } } } },
//组件的销毁 //删除组件对应的Dom节点 destroy : function(){ if(!this.isDestroyed){ if(this.fireEvent('beforedestroy', this) !== false){ this.destroying = true; //触发销毁之前函数,可以“趁机”做一些工作 this.beforeDestroy(); //如果有对应容器,移除 if(this.ownerCt && this.ownerCt.remove){ this.ownerCt.remove(this, false); } if(this.rendered){ this.el.remove(); if(this.actionMode == 'container' || this.removeMode == 'container'){ this.container.remove(); } } // Stop any buffered tasks if(this.focusTask && this.focusTask.cancel){ this.focusTask.cancel(); } this.onDestroy(); //注销组件 Ext.ComponentMgr.unregister(this); this.fireEvent('destroy', this); //消除监听 this.purgeListeners(); this.destroying = false; this.isDestroyed = true; } } },
相关文章推荐
- 23种设计模式总结<转>
- MySQL数据库优化总结 &lt;转&gt;
- 设计一个具有健壮性,灵活性,可重用性的Web应用架构(二)--->实验总结
- MVC Kendo总结之-----> CheckBox
- Quartz调度框架应用总结<1>
- Orace数据库锁表的处理与总结<摘抄与总结三>
- Linux初学笔记之<cd -和 cd 和whereis命令>
- 集合——>心德总结
- Java【多线程知识总结(10)】线程通信之wait()与notify()的运用--模拟指挥官指挥2个连队交替轰炸战区<另外的写法>
- Android中常常使用shape来定义控件的一些显示属性,今天看了一些shape的使用,对shape有了大体的了解,稍作总结: 先看下面的代码: <shape>
- ListView的Adapter使用 之 初学ArrayAdapter<String>
- Jsp-->第二次上课总结
- ARM学习总结1->寄存器初始值问题
- 读<<编写可读代码的艺术>>总结
- Java总结<二>
- JPA开发总结<六>--联合主键
- XML——>总结之Schema
- Android初学笔记之<handler.obtainMessage()方法理解>
- Android初学笔记之<Handler理解>
- <杂谈1002>HTML作为GUI前段,Java/NDK作为业务后端开发方式总结