`

Ext container 架构分析

阅读更多

 BoxComponent继承了Component,主要是实现了设置组件的宽度、高度以及位置(相对于容器或相对于document.body),他的实现较为简单,需要注意的是:
    1.BoxComponent可以通过resizeEl属性设置进行调整大小的对象,positionEl属性设置调整位置的对象,并且在render事件中进行设置,将属性封装为Ext.element对象;
    2.setSize和setPosition方法是在afterRender事件中被触发的,换句话说,组件调整位置和大小是在渲染后进行的。
onRender : function(ct, position){
Ext.BoxComponent.superclass.onRender.call(this, ct, position);
if(this.resizeEl){
  this.resizeEl = Ext.get(this.resizeEl);
}
if(this.positionEl){
  this.positionEl = Ext.get(this.positionEl);
}
},
afterRender : function(){
Ext.BoxComponent.superclass.afterRender.call(this);
this.boxReady = true;
this.setSize(this.width, this.height);
if(this.x || this.y){
  this.setPosition(this.x, this.y);
}else if(this.pageX || this.pageY){
  this.setPagePosition(this.pageX, this.pageY);
}
}

  Ext.Containr继承了BoxComponent,在他的initComponent方法中,增加了对以下事件的支持: 'afterlayout','beforeadd','beforeremove','add','remove'。
Container主要实现了对layout和items的管理。

  首先,让我们看一下Container对于items的管理:
  你可能会发现大部分的Widget都支持在构建器中传入一个items数组以非常方便的形式构建该Widget的子组件,而该数组大部分情况是由json构成,让我们看个例子:
new Ext.menu.Menu({
id: 'mainMenu',
items: [
{
text: 'I like Ext',
checked: true,   // when checked has a boolean value, it is assumed to be a CheckItem
checkHandler: onItemCheck
},
{
text: 'Ext for jQuery',
checked: true,
checkHandler: onItemCheck
},
{
text: 'I donated!',
checked:false,
checkHandler: onItemCheck
}, '-', ...

那么,这些json对象看不到表示任何对象类型的属性(xtype),Widget是怎样正确解析这些json对象的呢? 魔术就发生在Container中,首先,在Container的构建器中,有如下的语句:
var items = this.items;//如果传递了items对象
if(items){
delete this.items;
if(items instanceof Array){//items对象可以是数组,也许这样写更清楚些:this.add(items)
this.add.apply(this, items);
}else{
this.add(items);
}
}
实际上,大多Widget都有自己的缺省的add的实现以满足自身的要求,Container也提供了一个缺省的add方法的实现如下:
add : function(comp){
if(!this.items){//如果未实现items数组,创建items数组
this.initItems();
}
var a = arguments, len = a.length;//如果传入的是数组则对每个元素进行递归调用add方法
if(len > 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 types[config.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.LAYOUTS[this.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();
      }
  }
}

分享到:
评论
1 楼 javatozhang 2012-11-19  
你好我想问您一下:在Container的initComponent方法中有如下代码(拷贝你的为例):
var items = this.items;//如果传递了items对象
if(items){
delete this.items;
if(items instanceof Array){//items对象可以是数组,也许这样写更清楚些:this.add(items)
this.add.apply(this, items);
}else{
this.add(items);
}
}
如下代码是 Container的add方法:
add : function(comp){
if(!this.items){//如果未实现items数组,创建items数组
//此处的this.items显然已经被删除了再调用this.initItems()方法在实例化this.itmes是什么意思。是不是有点繁琐???
this.initItems();
}
希望得到你透彻的回答。

相关推荐

    ext 颜色改变组件

    Ext.create('Ext.container.Viewport', { layout: 'fit', // 全屏布局 items: [{ xtype: 'colorfield', // 使用颜色选择组件 fieldLabel: '选择颜色', listeners: { select: function (component, newValue) ...

    Ext组件描述,各个组件含义

    **1.5 Container (Ext.Container)** - **xtype**: `container` - **功能描述**:Container 是一个可以包含其他组件的容器,可以定义布局和其他高级属性。 - **主要用途**:用作布局管理器,组织和管理子组件。 ###...

    Ext MVC 项目示例

    通过`Ext.container.Viewport`或`Ext.Component`创建视图,并通过数据绑定将模型数据呈现到界面上。 3. **控制器(Controller)**: 控制器作为模型和视图之间的纽带,处理用户交互,更新模型数据,以及管理视图的...

    ext学习文档

    - **核心Core**: 探讨了EXT的核心功能和架构。 - **Javascript中的作用域(scope)**: 解释了作用域的概念及其在EXT中的重要性。 #### 5. EXT程序规划入门 - **事前准备**: 强调了在开始编程之前需要做哪些准备...

    ext4 表格分页实例代码

    Ext.create('Ext.container.Viewport', { layout: 'fit', // 全屏布局 items: [grid] }); ``` 在上述代码中,`data.json`应替换为实际的数据接口,返回JSON格式的数据,包含`data`属性,其值是一个数组,表示当前...

    Ext JS in Action

    通过对架构、设计理念和开发模式的介绍,帮助读者理解为什么Ext JS能够成为构建复杂Web应用的理想选择。 - **Back to the Basics (回归基础)**:介绍了Ext JS的基础知识,包括核心类库、DOM操作以及基本的UI组件等...

    Ext Htmleditor 支持上传图片

    Ext.create('Ext.container.Viewport', { layout: 'fit', items: [editor] }); } }); ``` 5. 安全与优化 为了提高用户体验和安全性,你需要考虑以下几点: - 图片尺寸限制:限制上传图片的最大尺寸,避免...

    Ext Js权威指南(.zip.001

    9.2.2 ext.container.abstractcontainer和ext.container.container的配置项、属性、方法和事件 / 434 9.2.3 将body元素作为容器:ext.container.viewport / 435 9.3 面板 / 436 9.3.1 面板的结构 / 436 9.3.2 ...

    ext-3.0框架源码

    2. **MVC架构**:EXT 3.0引入了MVC模式,帮助开发者将业务逻辑、视图展示和数据模型分离,提高了代码的可维护性和可扩展性。 3. **数据绑定**:框架支持双向数据绑定,当模型层的数据发生变化时,视图会自动更新,...

    Ext in Action(Ext3.2)

    - **组件与容器**:Ext JS 中的所有 UI 元素都是通过组件(Component)来表示的,而容器(Container)则用来组织这些组件。组件负责具体的 UI 表现,而容器则负责布局管理。 - **事件驱动**:Ext JS 采用事件驱动...

    EXT 中文手册

    容器模型则负责管理组件的层次结构和布局,如`Ext.container.Container`就是一个典型的容器组件,可以包含其他子组件。 #### 结语 EXT作为一款成熟的前端框架,不仅提供了丰富的UI组件和强大的功能,还注重于...

    Ext做的例子右键菜单设置forward跳转b/s版

    Ext.create('Ext.container.Viewport', { layout: 'fit', // 全屏布局 items: { xtype: 'panel', // 创建面板 html: '右键点击我试试', listeners: { // 添加监听器 contextmenu: function (component, event...

    Ext圖片上傳、刪除、查看.net源碼

    图片的缩略图可以使用`Ext.view.View`或`Ext.container.Container`来创建,结合`Ext.Image`组件显示。同时,可能还会用到`Ext.toolbar`来添加操作按钮,如“上传”、“删除”。 图片上传功能的核心是通过AJAX与...

    Ext.JS.4.First.Look

    - **布局容器的增强**:Ext JS 4中的容器类(Container)得到了改进,支持更复杂的嵌套布局。 - **响应式设计支持**:随着移动设备的普及,Ext JS 4也提供了响应式设计的支持,能够自动适应不同屏幕尺寸的显示需求。...

    Extjs4之MVC应用架构

    Ext.create('Ext.container.Viewport', { layout: 'fit', items: [ { xtype: 'panel', title: '用户列表', html: '用户列表将显示在此处' } ] }); } }); ``` ##### 2. 定义控制器 接下来定义一个控制器...

    Ext MVC案例

    在Ext MVC中,视图通常由`Ext.container`或`Ext.component`的子类构成,如面板、表格、按钮等。通过绑定模型数据,视图可以实时反映模型的变化。 3. **控制器(Controller)**: 控制器作为模型和视图之间的桥梁,...

    ExtJS4_官方指南:MVC架构_简体中文版

    Ext.create('Ext.container.Viewport', { layout: 'fit', items: [{ xtype: 'panel', title: 'Users', html : 'List of users will go here' }] }); } }); ``` 这段代码定义了一个名为'AM'的全局命名空间...

    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(4) 源代码

    在本教程中,我们将深入探讨如何利用Ext JS的MVC架构和Asp.Net MVC 3框架,共同构建一个简易的CMS(内容管理系统)的后台用户管理模块。这是一系列教程的第四部分,主要关注源代码的实现。 首先,我们要了解Ext JS...

    ext 嵌入editarea 实现代码 源代码

    这可以通过定义EXTJS组件,如`Ext.container.Viewport`或`Ext.window.Window`来实现。 3. **初始化EditArea**:在EXTJS容器的渲染事件中,调用EditArea的初始化函数,指定编辑器的ID和配置项。配置项可以设置编辑器...

    ExtTreePanel新增节点

    Ext.create('Ext.container.Viewport', { layout: 'fit', items: [tree] }); } }); ``` 7. **注意事项** - 确保`TreeStore`的数据源已加载,否则无法找到正确的父节点。 - 添加节点时,如果需要动态加载子...

Global site tag (gtag.js) - Google Analytics