您的位置:首页 > 产品设计 > UI/UE

初学Ext UI组件总结及(一)-- >读Ext.Component源码学习笔记

2012-02-13 23:11 246 查看
为了可以缓解审美疲劳,写出自己的Ext 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;

}

}

},





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: