首页 > 代码库 > ExtJS 快速入门 - 简介

ExtJS 快速入门 - 简介

本文不停更,不罗嗦,上货:
目前:
ExtJS提供2种使用协议:GPL(免费) 和 商业协议(付费)。
区别请自行摆渡悠。

Ext JS发展简史
YUI-Ext的作者Jack Slocum(杰克.斯洛克姆)打算对基于BSD协议的Yahoo User Interface (YUI)库进行自定义的扩展,但后来一度风头盖过其父辈YUI;
2006年底,YUI-Ext被简化为Ext,反映了它作为一个框架的成熟和独立。
该公司成立于2007年初,Ext现在为双执照,使用LGPL和一个商业执照;
2007年4月1日,发布1.0正式版,现在的版本为6.0;
4.0开始引入了MVC/MVVM风格的应用架构和SCSS;
5.0开始,不再支持老旧浏览器,如IE5、6、7等;
6.0开始,Sencha Touch和ExtJS合二为一,标志着用户可以开发既能支持传统桌面、又支持平板或手机的应用

Ext JS框架提供了对MVCMVVM应用程序架构的支持。这两种架构方式有一些思想是相同的,都是关注于将应用程序代码和业务逻辑分离

What is MVC?

在一个MVC框架中,大多数的类或者是模型(Models),或者是视图(Views),或者是控制器(Controllers)。用户(user)与视图(Views)交互,视图(Views)显示模型(Models)中的数据(data)。这些交互都被控制器(Controllers)监控,为了响应交互当需要时,控制器(Controllers)会更新模型(Models)和视图(Views)。

通常情况下,模型(Model)和视图(View)都不知道彼此的存在,因为控制器(Controller)对直接更新负主要责任。一般来讲,在一个应用程序中控制器(controllers)包含了大多数的应用逻辑。在理想情况下视图(views)会包含一点点业务逻辑。模型(models)主要是一个用户数据接口,包含着管理变化数据的业务逻辑。

MVC的目标是清晰的划分应用程序中各个类的职责。因为每一个类都有明确的职责,在大型的应用环境中,它们就暗暗解耦了。这就让应用程序容易测试和维护,代码复用性也加强了。

What is MVVM?

MVC和MVVM的最大的区别就是MVVM有一种叫做视图模型(viewmodel)的抽象视图。视图模型利用一种叫作数据绑定(data binding)的技术将模型的数据和视图的展示之间的变化进行调和。

结果是,模型和框架完成尽可能多的工作,最大限度地减少或消除应用程序逻辑直接操作视图

MVC and MVVM

为了理解如何在你的应用程序中选择合适的框架,首先我们应该进一步定义各种缩写代表什么:

(M:Model)模型:这是您应用程序的数据。一组类(称为“模型”)定义了它们数据的字段(如一个User模型有两个字段:用户名和密码)。通过数据包模型知道如何展示自己,模型也能通过关联于其它模型联系。

模型通常和Stores联合使用,给表格和其他组件提供数据。对于你可能需要的数据逻辑(比如验证、转换等)在模型(Models)中定义是比较理想的。

(V:View)视图:一个任何类型的组件是一个视图,视图即是视觉表示。例如:网格(grids),树(trees)和面板(panels)都是视图(views)。

(C:Controller)控制器:控制器是维护你的视图逻辑的(view’s logic),并使你的应用程序正常工作。控制器的工作可能包括渲染视图、路由、实例化模型,和任何其他类型的应用程序逻辑。

(VM: ViewModel)视图模型:视图模型是一个类,它管理视图的数据。它允许感兴趣的组件绑定和数据更改通知。

对于你的框架代码,这些应用程序架构提供结构化和一致性。按照约定,我们的建议将对你们有重要的好处:

每个应用程序在相同的方式工作,所以你只需要学一次。

很容易在应用程序之间共享代码。

您可以使用Sencha Cmd创建优化的生产版本的应用程序。(后续会提到)。

一个EXT JS的应用程序的UI用户界面是有一个或者多个部件构成的组件。所有的组件都是Ext.Component类的子类,允许它们参与自动化生命周期管理包括实例化,渲染,大小,定位还有销毁。Ext JS提供了一系列有用的组件,任何组件可以很容易地扩展到创建一个定制的组件。

组件的继承关系 !!!!!![非常非常重要的组件]

容器是一个特殊的组件类型,它可以包含其他组件。一个典型的应用程序是有许多嵌套的组件像树状结构哪有的组件继承结构。容器负责管理他们的子组件的生命周期,包含创建,渲染,大小还有位置和销毁。一个典型的应用程序的组件继承从顶层的Viewport开始,它还有其它的容器嵌套在里面。

技术分享

子组件通过使用容器的items配置增加到容器中,下面的例子使用Ext.create()创建初始化了两个面板,然后作为Viewport的子组件增加到Viewport中。

var childPanel1 = Ext.create(‘Ext.panel.Panel‘, {
    title: ‘Child Panel 1‘,
    html: ‘A Panel‘
});

var childPanel2 = Ext.create(‘Ext.panel.Panel‘, {
    title: ‘Child Panel 2‘,
    html: ‘Another Panel‘
});

Ext.create(‘Ext.container.Viewport‘, {
    items: [ childPanel1, childPanel2 ]
});

容器使用布局管理器来管理组件的大小还有位置,想要获取关于布局的更多信息,请访问 布局和容器指南

XTypes和懒加载

每一个组件都有一个符号名叫做xtype。像Ext.panel.Panel就有一个xtype名叫做‘panel’, 组件的API文档 列出了所有的组件的xtype。上面的例子展示了如何增加一个已经存在的组件到一个容器中。然而,在大型的应用程序中,着不是理想的,因为不是所有的组件都要被实例化,一些组件可能永远不需要被初始化,这取决于你的应用程序。例如,一个使用tab panel的应用程序只需要获取用户点击之后的那个tab的内容。这就是xtypes派上用处的地方通过允许容器的孩子在前置进行配置,需要的时候才进行实例化。

下面的示例代码演示了懒实例化和呈现一个使用选项卡面板的容器的子组件。每个标签都有一个事件侦听器,显示一个警告标签时呈现。

Ext.create(‘Ext.tab.Panel‘, {
        renderTo: Ext.getBody(),
        height: 100,
        width: 200,
        items: [
            {
                // Explicitly define the xtype of this Component configuration.
                // This tells the Container (the tab panel in this case)
                // to instantiate a Ext.panel.Panel when it deems necessary
                xtype: ‘panel‘,
                title: ‘Tab One‘,
                html: ‘The first tab‘,
                listeners: {
                    render: function() {
                        Ext.MessageBox.alert(‘Rendered One‘, ‘Tab One was rendered.‘);
                    }
                }
            },
            {
                // xtype for all Component configurations in a Container
                title: ‘Tab Two‘,
                html: ‘The second tab‘,
                listeners: {
                    render: function() {
                        Ext.MessageBox.alert(‘Rendered One‘, ‘Tab Two was rendered.‘);
                    }
                }
            }
        ]
    });

允许这段代码,会立即产生第一个tab的alert弹出框。这个发生是因为这是默认的tab页签,所以容器就立即调用病实例化容器的Tab Panel。

技术分享

第二个tab框直到点击的时候才会弹出,这就显示了需要的时候才会渲染,就是说tab页签激活的时候才会通知render事件。
技术分享

显示和隐藏

所有的组件都是在show和hide方法中构造的。用来隐藏组件的默认的css方法是“display:none”但是通过hidemode配置的时候就有所变化了:

var panel = Ext.create(‘Ext.panel.Panel‘, {
        renderTo: Ext.getBody(),
        title: ‘Test‘,
        html: ‘Test Panel‘,
        hideMode: ‘visibility‘ // use the CSS visibility property to show and hide this
component
    });

    panel.hide(); // hide the component

    panel.show(); // show the component

浮动组件

浮动组件是通过css绝对路径将文档放置在外的,并且不在参与组件的容器的布局的。有些组件像Windows是默认的浮动,所有的组件都可以通过配置来实现浮动:

var panel = Ext.create(‘Ext.panel.Panel‘, {
    width: 200,
    height: 100,
    floating: true, // make this panel an absolutely-positioned floating component
    title: ‘Test‘,
    html: ‘Test Panel‘
});

上述代码初始化了一个panel,但是没有渲染。正常情况下,一个组件或者有一个renderTo配置或者当做一个子组件增加到组件的容器中,但是当是浮动组件的时候,都不需要了。浮动组件会在第一次调用show方法的时候被渲染

?
1
panel.show(); // render and show the floating panel
下面有一些对浮动组件来说可以进行配置的一些方法

1.draggable:可以拖动屏幕周围浮动组件。

2.shadow:定制的外观浮动组件的影子。

3.alignTo:将浮动组件指定到特定的元素。

4.center() 将组件浮动到组件的中心

创建自定义组件

成分或者扩展
当创建一个新的UI类的时候,该类必须做出决定是否应该拥有一个组件的一个实例,或扩展组件

根据功能需要继承一个最近的基类是被推荐的。这是因为EXT JS提供的自动生命周期管理包含了当需要的时候自动渲染,自动大小,自动调整位置当通过布局管理的时候,也会自动的从容器中移除和销毁。

通过组建创建新类比较容易,不推荐使用一个新的类拥有一个组件在外部去渲染和管理。

子类
类系统 让扩展extjs框架变得非常容易。Ext.Base是所有Ext JS类的构建块,原型和这个类的静态成员被其他类继承。

尽管你可以再低水平的情况下增加一个方法,但是开发人员在通常情况下会想通过高一点的继承链来开始。

下面这个例子创建了一个Ext.Component的子类:

Ext.define(‘My.custom.Component‘, {
    extend: ‘Ext.Component‘,

    newMethod : function() {
       //...
    }
});

这个例子创建了一个新的类‘My.custom.Component’,它继承了Ext.Component的所有方法属性等。

模板方法:EXT JS使用 模板方法模式 代表子类,行为。

这意味着,在继承链中的每一个类都可能贡献一个额外的逻辑组件的生命周期中的某些阶段。每一个类实现自己的独有的行为,并且允许其他继承自这个类的实现自己特有的逻辑。

典型例子就是 渲染 方法,render 是定义在Component类中的一个方法,它对初始化组件的呈现阶段生命周期负责。render不能被重写,但是可以调用onRender方法在处理子类实现的时候可以调用来实现自己的特有属性方法。每一个onRender方法必须调用父类的onRender方法在贡献自己额外逻辑的时候。

下面的表格展示了onRender模板方法的功能。

render方法被调用(通过布局管理器来实现的)。这个方法不能被重写也是通过Ext基类实现的,它调用this.onRender方法,这个方法实现了当前子类(如果被实现了的话)。这个就调用父类的版本,以此类推。最终,每个类贡献了自己的功能,控制返回render方法。

技术分享

下面是一个组件子类实现

onRendExt.define(‘My.custom.Component’, {
extend: ‘Ext.Component’,
onRender: function() {
this.callParent(arguments); // call the superclass onRender method

    // perform additional rendering tasks here.
}

});

得注意的是,许多模板方法都有自己对应的事件,例如渲染事件,是在渲染事件出发的时候执行。然而,当子泪花的时候,它必须使用模板方法在重要声明周期阶段执行类逻辑而不是事件。事件可以通过编程来停止或者暂停。

下面是一些子类可以实现的组件的模板方法

initComponent:这个方法被类构造方法唤醒,用来初始化数据,设置属性,附加事件处理。

beforeShow:在组件显示之前被调用

onShow: 允许添加行为操作,在超类的onShow方法被调用之后就组件就可见了。

afterShow: 方法在组件被显示之后调用。

onShowComplete:这个方法在afterShow完成之后被调用

onHide:在隐藏的时候可以增加一些操作,调用超类的onHide方法之后,组件就看不见了。

afterHide:组件隐藏之后的事件处理

onRender:渲染的时候执行的事件

afterRender:渲染完成之后可以增加的额外操作。在你这个阶段,组件的元素已经根据配置或者css雷鸣增加了类型,并且将会被配置可见性和启用状态。

onEable:组件可用性,调用超类的这个事件的时候,组件就可以使用了

onDisable:组件不可用处理的时候的事件。

onAdded:当组件被增加的时候,组件被增加到容器的时候。在这个阶段,组件在父类容器的子条目集合中,当调用超类的这个方法之后,容器就是被展现,如果有引用,引用也会被设置。

onRemoved:被移除的时候的事件。这时候,组件以及从父容器之中移除了,但是还没有销毁。调用超类的这个方法之后,容器就不会被展现了。

onResize:大小变化的时候的调用事件

onPosition:位置变化的时候调用的事件

onDestroy:销毁的时候的事件

beforeDestroy:销毁之前

afterSetPosiotion:设置位置之后

afterComponentLayout:组件布局之后

beforeComponentLayout:组件布局之前

我们该扩展哪个类

选择一个最好的继承类是一个效率的问题,功能基类必须要提供的。有一种趋势就是总是继承Ext.panel.Panel当你设置UI组件的时候,这些组件需要被渲染和管理的时候。

Panel类有如下能力:

Boder

Header

Header Tools

Footer

Footer Buttons

Top toolbar

Buttom toolbar

Containig and managing child Components

如果这些不需要,那么使用Panel类就是一种资源浪费。

组件
如果需要的组件UI不需要包含其他组件,那就是,如果只是封装HTML执行某种形式的需求,那么扩展Ext.Component是合适的。举例来说,下面这个类是一个组件包装了HTML的图片元素,允许通过图片的src属性来设置和获取。在加载的时候也会有方法被触发。

Ext.define(‘Ext.ux.Image‘, {
    extend: ‘Ext.Component‘, // subclass Ext.Component
    alias: ‘widget.managedimage‘, // this component will have an xtype of ‘managedimage‘

    autoEl: {
        tag: ‘img‘,
        src: Ext.BLANK_IMAGE_URL,
        cls: ‘my-managed-image‘
    },

    // Add custom processing to the onRender phase.
    // Add a ‘load‘ listener to the element.
    onRender: function() {
        this.autoEl = Ext.apply({}, this.initialConfig, this.autoEl);
        this.callParent(arguments);
        this.el.on(‘load‘, this.onLoad, this);
    },

    onl oad: function() {
        this.fireEvent(‘load‘, this);
    },

    setSrc: function(src) {
        if (this.rendered) {
            this.el.dom.src = http://www.mamicode.com/src;"hljs-keyword">else {
            this.src = http://www.mamicode.com/src;"hljs-function">function(src) {
        return this.el.dom.src || this.src;
    }
});

使用如下:

var image = Ext.create(‘Ext.ux.Image‘);

Ext.create(‘Ext.panel.Panel‘, {
    title: ‘Image Panel‘,`这里写代码片`
    height: 200,
    renderTo: Ext.getBody(),
    items: [ image ]
});

image.on(‘load‘, function() {
    console.log(‘image loaded: ‘, image.getSrc());
});

Container容器
如果组件包含其他组件,那么就选容器比较适合了。在面板级别,需要重点记忆的是,Ext.layout.container.Container不是用来被渲染和管理子组件的。

容器拥有下面这些方法

onBeforeAdd:子组件增加的时候这个方法被调用。通过了新组件,可以用来修改组件,或准备容器。返回false中止添加操作。

onAdd:组件被增加完成的时候调用。它是通过组件已被添加。这种方法可以用于更新任何内部结构可能依赖于状态的子元素。

onRemove:它是通过组件已被添加。这种方法可以用于更新任何内部结构可能依赖于状态的子元素。

beiforeLayout:这个方法被调用之前容器已经制定了(如果需要)并呈现它的子组件。

afterLayout:调用该方法后,集装箱已经制定了(如果需要)并呈现它的子组件。

Panel面板
如果UI界面需要头信息,底部信息,工具条,那么Ext.panel.Panel就是一个合适的选择。
重要的是:一个面板是一个容器。重要的是要记住,布局是用于呈现和管理子组件。

这类扩展Ext.panel。面板通常非常特定于应用程序的,一般用于聚合其他UI组件(通常是容器,或表单字段)配置布局,并提供操作手段所包含的组件通过控制tbar bbar。
面板拥有如下的模板方法

afterCollapse:当折叠的时候被调用

afterExpand:当展开的时候被调用

onDockedAdd:当停靠的时候调用

ondockedRemove当停靠移除的时候调用。

extjs 组件生命周期
组件有三种类型:基本组件,工具栏组件,表单组件。

下面的每一个阶段都是从 Component 继承下来的类的生命周期中重要的阶段。

第一个阶段:初始化
1、应用配置选项
从 Component 继承下来的类并不需要提供(通常没有提供)一个独立的构造器。
Component 的构造器不仅应用从子类传过来的配置选项,同时它还做了以下的工作。
2、创建事件
任何组件都有 enabled、disable、beforeshow、show、beforehide、hide、bdforerender、render、
beforedesctory、destory 事件,这些事件可以被任何组件调用。
3、在 ComponentMgr 中注册组件实例
这样就可以通过 Ext.getCmp 被获得实例引用。
4、调用 initComponent 方法
这是一个最重要的初始化步骤,它是做为一个模板方法,子类可以按需要重写这个方法。
被创建的类的 initComponent 首先被调用,然后通过组件 提供的 superclass.initComponent 向
上调用。这个方法非常容易被实现,如果需要,你还可以任意覆盖构造器逻辑。
5、状态被始化
如果组件有状态,已保存的状态会被重新加载。
6、加载插件
如果组件有指定插件,则插件会在这时候被初始化。
7、组件呈现
如果有配置 renderTo 或 applyTo,组件会马上被呈现输出,否则,它会被延迟输出,直
到组件被显式调用显示,或被它的容器所调用输出。

第二阶段:呈现
1、触发 beforerender 事件
这是一个可取消的事件,如果需要给提供处理函数来阻止组件的继续呈现输出。
2、设置容器
如果没有父容器被指定,默认它的父对象被指定为它的容器。
3、调用 onRender 方法
这是为子类执行呈现工作的一个非常重要的方法,这是一个模板方法,在子类中可以根
据需来重写它的实现逻辑。直接被创建的类的 onRender 首先被调用,然后它可以通过
superclass.onRender 来调用基类的 onRender 方法。这个方法很容易被重新实现,如果需要你
可以在继承关系的任意类中重写这个方法。
4、不隐藏组件
默认,大多数组件都会通过设置像 x-hidden 这个样式来使它隐藏。当 autoShow 设置为
true 时,这个隐藏功能的样式会被移除。
5、应用自定义样式
所有的 Component 子类都支持指定 cls 配置属性,通过它可以为 Component 所呈现的
HTML 元素指定 CSS 样式。通过添加组件的 cls 属性,使用标准的样式规则,是一个自定义
可视组件显示效果的非常完美的方法。
6、render 方法被触发
简单的通知组件已经被成功的呈现了。
7、调用 afterRender
这是另一个模板方法,子类根据逻辑需要可以重新实现或覆盖该方法。所有的子类可以
通过调 superclass.afterRender.来调用父类的方法。
8、组件隐藏或不可用
根据配置选项的值来设置。
9、状态事件被初始化
可以状态化的组件会定义一些事件来指定状态的初始化和保存。如果提供,这些事件会
被添加。

第三阶段:销毁
1、触发 beforedestroy 事
这是一个可取消的事件,如果需要,可能通过提供事件代理来阻止组件被销毁。
2、调用 beforeDestroy 方法
又一个模板方法,在子类中可以重新实现和调用父类的方法。
3、移除事件监听者(代理)
如果组件已被呈现,则移除它底层的 HTML 元素的事件监听列表,然后将元素从 DOM
中移除。
4、onDestroy 被调用
这个还是一个模板方法,在子类可以重新实现。这里需要注意的是,容器类提供了一个
默认的 onDestroy 实现,它会循环销毁它的成员组 。
5、组件实例从 ComponentMgr 中反注册
不可以再通过 Ext.getCmp 获取到对象实例。
6、destroy 事件被触发
这只是一个简单的提醒,表示组件销毁成功。
7、移除 Component 上的事件代理
组件可以独立于元素,自己拥有事件代理,如果存在则移除它们。

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    ExtJS 快速入门 - 简介