在下一章咱们会构建一个示例项目,而在这以前,你须要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目。这一章咱们将学习如下知识点:html
class system(类系统)java
Ext JS 提供了不少功能,使得它建立和处理类变得简单。如下是在 Ext JS 6 的类系统中的几大组成类:git
Ext 是一个全局单例的对象,在 Sencha library 中它封装了全部的类和许多实用的方法。许多经常使用的函数都定义在 Ext 对象里。它还提供了像其余类中一些频繁使用的方法的快速调用。github
咱们看一下在 Ext 类中定义的方法和属性:数组
这里应用是用 Ext.application 方法初始化的。这个方法的参数是一个 Ext.app.Application 对象,这个方法会加载 Ext.app.Application 类,并在页面加载完成后开始应用给定的配置。app
Ext.app.Application 这个类表明咱们的整个应用,这在第1章(入门指南)讲过,讲过的吧?是吧?下面是 Ext.app.Application 的使用例子:框架
1
2
3
4
5
6
7
|
Ext.application({
name: 'MyApp',
extend:'MyApp.Application',
launch: function() {
}
}) ;
|
上面代码建立一个名为 MyApp 的全局变量。咱们的应用里全部的类都将归属于在这样一个命名空间下面。这将下降全局变量产生冲突的可能。dom
你能够用这个方法定义或者重写一个类。 这个方法有三个参数,如如下代码所示。 在这里 name 参数是你要定义的类名,data 参数是应用于这个类的属性,callback 是可选参数,这个函数将会在这个类被建立后调用:异步
1
|
Ext.define(name,data, callback)
|
下列代码建立一个名为 Car 的类:ide
1
2
3
4
5
6
7
8
9
10
11
|
Ext.define('Car', {
name: null,
constructor: function(name) {
if (name) {
this.name = name;
}
},
start: function() {
alert('Car started');
}
}) ;
|
你还可使用 define 继承扩展一个类:
1
2
3
4
5
6
|
Ext.define('ElectricCar', {
extend: 'Car',
start: function() {
alert("Electric car started");
}
}) ;
|
若是你想替换一个父类方法的实现,你可使用 Ext.define 来重写这个方法,如如下代码所示:
1
2
3
4
5
6
7
|
Ext.define('My.ux.field.Text', {
override: 'Ext.form.field.Text',
setValue: function(val) {
this.callParent(['In override']);
return this;
}
});
|
细心的同窗可能发现了当咱们继承和重写时使用的属性是不一样的,继承咱们使用 extend 而重写使用 override ,这二者之间有什么区别呢?你必定感到疑惑,这里我很是有必要给你解释清楚,听我慢慢道来。
首先说继承并扩展一个类,这等同因而一个新的类,仍然能够在这个新的类里增长本身独有的方法和属性或者重写父类的方法。
1
2
3
4
5
6
7
8
|
Ext.define('MyApp.view.main.Test', {
extend: 'Ext.grid.Panel',
xtype: 'maintest',
title: 'Personnel',
say:function(){
alert(123);
}
});
|
这里我继承了 gridpanel 类,并增长了一个 say方法,如下是输出调用 say 方法的运行结果。
这应该很好理解,Test 继承了 grid panel 以后是一个新的类了,而这里若是建立 Ext.grid.Panel 对象是调用不了 say 方法的。
那么如今我把 extend 改成 override 咱们再看一下:
1
2
3
4
5
6
7
8
|
Ext.define('MyApp.view.main.Test', {
override: 'Ext.grid.Panel',//改成 override 了
xtype: 'maintest',
title: 'Personnel',
say:function(){
alert(123);
}
});
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
name: 'MyApp',
requires: [
'MyApp.view.main.Main',
'MyApp.view.main.Test'//我这里引入了 Test
],
stores: [
// TODO: add global / shared stores here
],
launch: function () {
var test = Ext.create("MyApp.view.main.Test",{
title: 'Personnel'
});
test.say();
},
onAppUpdate: function () {
Ext.Msg.confirm('Application Update', 'This application has an update, reload?',
function (choice) {
if (choice === 'yes') {
window.location.reload();
}
}
);
}
});
|
运行结果:
咱们能够看到我只是简单的把 extend 替换成 override 就报错说不能识别的类名。可是上面我也是引入了它的引用的(requires),可见 extend 和 override 仍是有区别的,咱们不是重写(override)的是 grid panel 吗?那咱们试试建立一个 Ext.grid.Panel 对象试试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
name: 'MyApp',
requires: [
'MyApp.view.main.Main',
'MyApp.view.main.Test'
],
stores: [
// TODO: add global / shared stores here
],
launch: function () {
//这里改为了 grid panel
var test = Ext.create("Ext.grid.Panel",{
title: 'Personnel'
});
test.say();
},
onAppUpdate: function () {
Ext.Msg.confirm('Application Update', 'This application has an update, reload?',
function (choice) {
if (choice === 'yes') {
window.location.reload();
}
}
);
}
});
|
再次运行结果:
此次正常了,咱们使用 Ext.define 定义的类,使用了 override 重写组件,发现并不能新建咱们定义的类,而是被重写的父类被新增了 say 方法。
因此总结一下,extend 会建立一个新的类,并继承父类的属性和方法,你也能够重写父类的方法。而 override 并不会建立一个新的类,而是修改这个被重写的父类。
若是你想建立一个单例类,那么你在定义类时用 singleton 属性,如如下代码所示:
1
2
3
4
5
6
|
Ext.define('Logger', {
singleton: true,
log: function(msg) {
console.log(msg);
}
}) ;
|
你可使用下列代码来建立一个类的实例:
1
|
Ext.create(Class,Options);
|
下列代码建立了一个 ElectricCar 类的实例,并传递一个值(name):
1
|
var myCar = Ext.create('ElectricCar',{ name: 'MyElectricCar' }) ;
|
若是 Ext.Loader 是开启的,Ext.create 执行时若是 ElectricCar 类不存在将会自动的下载对应的 JS 文件。默认 Ext.Loader 是开启的;你能够经过如下方式来关闭它。
1
2
3
|
Ext.Loader.setConfig({
enabled: true
});
|
这里你也可使用 new 关键字来建立一个实例,如如下代码所示;但是若是这个类不存在,使用 new 关键字建立实例并不会自动下载对应的 JS 文件:
1
|
var myCar = new ElectricCar('MyElectricCar');
|
这个函数在页面加载完成后调用:
1
2
3
4
5
6
|
Ext.onReady(function(){
new Ext.Component({
renderTo: document.body,
html: 'DOM ready!'
});
}) ;
|
大多时候,在你的代码里不会用到 onReady 这个方法,由于 Ext 建议你一个应用就是一个页面(单页式应用),只有一个页面的话天然没有那么多场景会须要用到。只有在极少数的一些特殊状况,你可能须要用它。这里要强调一点,若是你具备使用 jQuery 的基础,不要把 onReady 方法像 jQuery 中的 $( document ).ready() 那样频繁使用。
当定义一个类时,你能够为这个类增长一个便于记忆的别名。例如: Ext.panel.Panel 的别名为 widget.panel 。定义别名时,如如下代码所示指定 alias属性:
1
2
3
4
|
Ext.define('Ext.panel.Panel', {
extend: 'Ext.container.Container',
alias: 'widget.panel'//这里是定义的别名,
});
|
你也可使用 xtype 为这个类给定一个别名。这个 xtype 是很是有用的,当你以指定 xtype 的方式应用部件时,并不会建立实例,而是在真正调用展现的时候才会建立这个类的实例。在本章后面介绍 容器和布局 时你将会学到更多关于 xtype 的使用。
Ext.widget 方法是经过类的 xtype 快速建立部件的。
例如,不使用 widget 方法,你能够经过下列代码建立 Ext.panel.Panel 的实例:
1
2
3
4
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
title: 'Panel'
});
|
反之,经过如下方式快速建立 panel 的实例:
1
2
3
4
|
Ext.widget('panel', {
renderTo: Ext.getBody(),
title: 'Panel'
});
|
这里 panel 是一个容器,关于 panel 会在后面详细讲解。下面代码的做用至关于与上面:
1
2
3
4
|
Ext.create('widget.panel', {
renderTo: Ext.getBody(),
title: 'Panel'
});
|
注意: 你阅读此文档的同时,这里面的大部分代码都是能够运行的,你能够选择在你本地设备上或者在 Sencha Fiddle 上执行这些示例代码。你能够访问Sencha Fiddle 并将上面的代码键入到 launch 函数中,运行并查看结果。若是你访问了 https://fiddle.sencha.com 将会看到下列代码:
1
2
3
4
5
6
|
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.Msg.alert('Fiddle', 'Welcome to Sencha Fiddle!');
}
}) ;
|
如今,粘贴建立 panel 部件的代码如如下示例,运行并查看结果。复制粘贴时,注意单引号不要写成中文标点单引号:
1
2
3
4
5
6
7
8
9
|
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('widget.panel', {
renderTo: Ext.getBody(),
title: 'Panel'
});
}
}) ;
|
若是建立的实例是用 Ext.define 定义的,那么返回这个给定对象的类,不然返回 null:
1
2
|
var button = new Ext.Button();
Ext.getClass(button); // returns Ext.Button
|
经过它的引用或实例返回类名称:
1
|
Ext.getClassName(Ext.Button); //returns "Ext.Button"
|
这是全部 Ext 类的基础。全部的 Ext 类都继承自 Ext.Base。该类全部的原型和静态成员都会传递给继承它的类。
这是一个低级别的工厂类,用于经过 Ext.ClassManager 定义一个类。因此不该该在你的代码中直接访问;你应该使用 Ext.define。
它管理全部的类同时处理类反射。一般经过下面几个方法访问:
在本章咱们已经讨论使用过这些方法。
用于动态的加载依赖。一般使用 Ext.require 来指定依赖。当你定义一个类时,这样指定组件的依赖列表是一个很好的作法,如如下代码所示:
1
|
Ext.require(['widget.window', 'layout.border','Ext.data.Connection']);
|
若是你须要引入一个指定命名空间下全部的 组件/类 时,使用通配符,如如下代码所示:
1
|
Ext.require(['widget.*', 'layout.*', 'Ext.data.*');
|
使用如下语法排除掉不须要的类:
1
|
Ext.exclude('Ext.data.*').require('*');
|
用这种方式,依赖的类是异步加载的。若是在你定义的类中没有指定依赖的类,那么当使用 Ext.Create 建立实例时,若是它是未加载的,这时将会同步加载这些类文件。这对性能有必定的影响,因此当你定义类时,使用 Ext.require 指定所需的类老是更好的。
singleton:true 属性当前类初始化时,该实例是一个单例对象。
注意:定位类的文件路径是基于类名的。例如:MyApp.view.About 类的路径应该是 \myapp\view\ about.js 。
Events(事件)
一个事件能够是一个用户操做,一个 Ajax 调用的响应等等。
当你建立对象或者建立之后均可觉得这个对象添加监听器。下列示例代码为这个对象添加了一个 单击事件 的监听:
1
2
3
4
5
6
7
8
|
Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
listeners: {
click: function() {
Ext.Msg.alert('Button clicked!');
}
}
}) ;
|
你能够添加多个事件监听,如如下代码示例:
1
2
3
4
5
6
7
8
9
10
11
|
Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
listeners: {
mouseout: function() {
//Do something
},
click: function() {
// Do something
}
}
});
|
你也能够在对象建立以后,使用 on 方法为对象添加事件监听:
1
2
3
4
|
var button = Ext.create('Ext.Button');
button.on('click', function() {
//Do something
}) ;
|
一样的,你也可使用 on 方法一次添加多个事件的监听,如如下代码示例:
1
2
3
4
5
6
7
8
9
|
var button = Ext.create('Ext.Button');
button.on({
mouseover: function() {
//Do something
},
mouseover: function() {
//Do something
}
}) ;
|
You can also remove the listeners, but you need the reference to the function; you can’t use the anonymous function.
1
2
3
4
5
6
7
8
9
10
11
|
var HandleClick= function() {
Ext.Msg.alert('My button clicked!');
}
Ext.create('Ext.Button', {
listeners: {
click: HandleClick
}
}) ;
button.un('click', HandleClick);
|
你能够将监听器添加到 DOM 元素,以下所示。
假设在你的 HTML 代码中,有一个 div 元素 id=mydiv ,如如下代码所示:
1
|
< div id="mydiv"></div >
|
用下列代码为它添加事件监听:
1
2
3
4
|
var div = Ext.get('mydiv');
div.on('click', function(e, t, eOpts) {
// Do something
});
|
访问 DOM
有三种方法来访问 DOM 元素:get,query,和 select 。
get 方法是根据这个 DOM 元素的 ID 检索获取并封装为 Ext.dom.Element 对象:
1
|
var mydiv = Ext.get('myDivId');
|
这种方式基于传入的 CSS 选择器 从给定的根节点开始查找。它返回一个匹配选择器的元素(HTMLElement[]/Ext.dom.Element[])数组。若是没有匹配的,返回一个空值的数组对象。
在下面示例中,myCustomComponent.getEl().dom 是传递的根节点。Ext.query 将检索这个节点内的子元素,并返回一个数组包含 CSS class 为 ‘oddRow‘ 的的元素:
1
|
var someNodes = Ext.query('.oddRow', myCustomComponent.getEl().dom);
|
给出一些 CSS/XPath 选择器,Ext.select 方法返回一个 CompositeElement 类型的对象,表明一个元素的集合。
这个 CompositeElement 对象能够进行过滤,迭代,和对整个集合执行总体操做等等:
1
2
|
var rows = Ext.select('div.row'); ////Matches all divs with class
row rows.setWidth(100); // 这是设置全部元素的宽度为 100
|
你也能够用一行代码,以下所示:
1
|
Ext.select('div.row').setWidth(100);
|
在方法调用时经过指定多个搜索条件能够用来匹配多个元素:
1
|
Ext.select('div.row, span.title'); //匹配全部的 class 用 .row 的 div 元素,和匹配全部 class 用 .title 的 span 元素
|
当你使用 select ,它默认取 HTML body 做为根并从默认的 body 开始检索整个 DOM 树。你能够经过制定一个根元素来避免这种状况,这样它将只搜索给定的根的子节点。
1
|
Ext.get('myEl').select('div.row');
|
这儿使用了 ‘myEl’ 做为根节点。这将首先找到 id 为 ‘myEl’ 的元素,而后将在根元素(myEl)下面搜索出 class 为 ‘row’ 的 div 标签。
1
|
Ext.select('div.row', true, 'myEl');// This is equivalent to the previous line.
|
下列的查询方式会匹配 class 为 row 而且 title 属性值为 bar 的 div ,这个 div 属于其父元素的首个子元素:
1
|
Ext.select('div.row[title=bar]:first')
|
这容许你用 ID,xtype,和 属性查找一个组件。你能够全局搜索或者指定一个根组件。
下列查询将返回全部的 xtype 为 button 的组件:
1
|
Ext.ComponentQuery.query('button');
|
获得一个 id 为 foo 的组件,用如下代码:
1
|
Ext.ComponentQuery.query('#foo');
|
下列代码将返回全部的 xtype 为 button 而且 title 属性值为 my button 的组件:
1
|
Ext.ComponentQuery.query("button[title='my button']");; //or parent.query('textfield[title=my button]');
|
你也可使用嵌套选择器以下:You can also use nested selectors as follows:
1
|
Ext.ComponentQuery.query('formpanel numberfield'); // 这里获取 xtype 为 frompanel 下面的 xtype 为 numberfield 的组件
|
下列代码返回这个 parent 容器内匹配传递进来的选择器的第一个直接子组件,若是没有匹配上,返回 null 。
1
|
parent.child('button[itemId=save]');
|
一样的,你也可使用其余的方法,例如 nextNode, up, down, previousSibling 等等。
Ext JS 提供了一组丰富的组件和布局,这使在 Ext JS 中开发 UI 变得超级简单,甚至非专业 UI 开发人员也可以轻易的使用。
从简单的组件提及,例如 button 和 label ,到复杂的组件,例如 Tree Panel,Grids 等等,Ext JS 有大量的内置组件。全部的组件都派生自Ext.Component 类,它提供支持建立,重绘,渲染和处理组件。
全部的组件都有一个属性叫作 xtype 。它是很是有用的,它用在当你不想立刻实例化这个组件时,而是想让这个组件在实际被应用时才建立,就是咱们俗称的懒加载。
容器是一个特殊的组件类型,它可以持有其余组件。在 Ext JS 中 Ext.container.Container 类是全部的容器的基础类。
Ext.toolbar.Toolbar, Ext.panel.Panel, 和 Ext.Editor 是一些内置组件。这些组件都是能够包含其余组件。而像 Ext.button.Button 类就不是派生自Ext.container.Container ,因此它不可以包含其余组件。
一个典型的 Ext JS 应用包含一组嵌套的组件。看下面这个例子并思考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
Ext.create('Ext.panel.Panel', {
renderTo:Ext.getBody(),
width:700,
height:400,
items:[{
xtype: 'panel',
title: 'Panel 1',
},{
xtype: 'panel',
title: 'Panel 2',
height: 200,
items: [{
xtype: 'button',
text: 'Click Me'
}]
},{
xtype: 'panel',
title: 'Panel 3',
width: 150,
height: 100
}]
});
|
在前面的代码中,这是嵌套的组件,结构以下图所示:
上面的代码运行后将输出相似如下截图:
布局定义了包含的组件是如何定位的以及设定组件的尺寸大小。每个容器都有一个布局。默认布局是 auto 。这将不会为子组件指定任何关于位置和大小的规则。
在上面的图中,你可能已经注意到这些子组件只是一个接一个嵌套在父级容器中。这是在代码中由于咱们尚未为这些组件制定任何布局,默认状况下使用的是 auto 布局。
如今,让咱们在相同的代码里使用一些布局。下列示例中,咱们将使用 column 布局和 center 布局。
当你使用 column 布局,你能够指定 columnWidth 。全部的列的 columnWidth 的值的总和必须等于 1 。你也能够为一些列指定固定宽度,如如下代码所示。这里,Panel3 取了一个 150 的固定宽度,而后剩下的两列按照 columnWidth 的值分配剩下的宽度:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Ext.create('Ext.panel.Panel', {
renderTo:Ext.getBody(),
width:700,
height:400,
layout:'column',
items: [{
xtype: 'panel',
title: 'Panel 1',
columnWidth: 0.4,
height: 400,
},{
xtype: 'panel',
title: 'Panel 2',
columnWidth: 0.6,
layout: 'center',
height: 400,
items: [{
xtype: 'button',
text: 'Click Me'
}]
},{
xtype: 'panel',
title: 'Panel 3',
width: 150,
height: 400
}]
});
|
以上代码输出为:
updateLayout 是 Ext.container.Container 对象里的一个方法。这能够用来根据布局规则从新定位子组件。例如你修改了布局方式,须要动态的更新布局时。
大多数时候你不会用到这个 updateLayout 方法,然而有些时候你必须调用它。
这个 updateLayout 方法是在你重绘和当你添加或删除了一个组件时自动调用。有时候你可能须要它暂停一下,不是立刻就调用,特别是当你添加或删除多个子组件时。因此在这种状况下,你能够设置 suspendLayout 属性为 true ,一旦你完成添加或删除组件的操做,你能够设置 suspendLayout 为 false 并在你的代码中手动调用 updateLayout 方法。
一样的若是你想对整个框架中止更新布局,你能够调用 Ext.suspendLayouts() ,而后在你的操做完成后你能够经过调用 Ext.resumeLayouts(true) 恢复它。
如下是 Ext JS 中可用的布局:
这个布局使用 x 和 y 属性来指定组件的绝对定位:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
Ext.create('Ext.panel.Panel', {
renderTo:Ext.getBody(),
width:700,
height:400,
layout:'absolute',
items: [{
xtype: 'panel',
title: 'Panel 1',
x: 12,
y: 20,
height: 250
},{
xtype: 'panel',
title: 'Panel 2',
x: 200,
y: 150,
height: 200
},{
xtype: 'panel',
title: 'Panel 3',
x: 400,
y: 250,
width: 150,
height: 100
}]
});
|
这里所示的输出,你能够重叠组件由于他们用绝对位置定位的:
这个布局展现了在一个时间里只有一个内置的可支持折叠和展开的子级 panel 。瞧一下如下示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout: 'accordion',
items: [{
title: 'Item 1',
html: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
},{
title: 'Item 2',
html: 'some content here'
},{
title: 'Item 3',
html: 'empty'
}]
});
|
这里显示的输出,这个 Item 1 是展开的,而其余的 panel 是折叠的:
这个布局使你可以指定子级组件的大小,而这是相对于布局容器的。首先容器根据指定的锚点规则调整而后全部的子级组件再做调整:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout: 'anchor',
items: [{
title: 'Item 1',
html: 'Item 1',
anchor: '50%'
},{
title: 'Item 2',
html: 'Item 2',
anchor: '-20 -200'
},{
title: 'Item 3',
html: 'Item 3',
anchor: '-200'
}]
});
|
输入如如下截图:
这个布局容许你为子组件指定一个区域位置,例如 center,north,south,west 和 east。当你使用 border 布局时,在其内的组件必须有一个指定区域为 center,以下列代码所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout: 'border',
items: [{
title: 'Item 1',
html: 'Item 1',
region: 'center'
},{
title: 'Item 2',
html: 'Item 2',
region: 'east',
width: 200
},{
title: 'Item 3',
html: 'Item 3',
region: 'south',
height: 100
}]
}) ;
|
以上代码输出相似下列视图:
在此布局中,只有一个子组件是可见的,这个组件基本上充满整个容器。卡片布局通常应用在向导或者 tabs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout: 'card',
defaultListenerScope: true,
bbar: ['->',{
itemId: 'btn-prev',
text: 'Previous',
handler: 'showPrevious',
disabled: true
},{
itemId: 'btn-next',
text: 'Next',
handler: 'showNext'
}],
items: [{
index: 0,
title: 'Item 1',
html: 'Item 1'
},{
index: 1,
title: 'Item 2',
html: 'Item 2'
},{
index:2,
title: 'Item 3',
html: 'Item 3'
}],
showNext: function () {
this.navigate(1);
},
showPrevious: function () {
this.navigate(-1);
},
navigate: function (incr) {
var layout = this.getLayout();
var index = layout.activeItem.index + incr;
layout.setActiveItem(index);
this.down('#btn-prev').setDisabled(index===0);
this.down('#btn-next').setDisabled(index===2);
}
});
|
卡片布局的输出。当你点击 next 按钮,将会显示 Item 2 面板:
这种布局,容器的子组件在中间。在本章中开始介绍布局的部分,咱们已经有一个例子了。
用此布局,你能够将容器划分为指定数量的列并指定每列所占的大小。这个例子也在本章开始介绍布局的部分中能够找到。
在此布局中,子组件将会自适应容器的尺寸。以下:
1
2
3
4
5
6
7
8
9
10
11
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout: 'fit',
bodyPadding: 20,
items: [{
title: 'Item 1',
html: 'Fills the container',
}]
});
|
下列截图展现以上代码的输出。注意:Item 1 组件与父级容器之间的空隙是咱们指定了 bodyPadding 属性:
这种布局与 column 布局几乎是同样的,可是这种布局容许你拉伸列的高度。这里使用 flex 选项为子组件设置水平的相对值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout:{
type: 'hbox',
pack: 'start',
align: 'stretch',
},
items: [{
title: 'Item 1',
html: 'Item 1',
flex: 1
},{
title: 'Item 2',
html: 'Item 2',
width: 100
},{
title: 'Item 3',
html: 'Item 3',
flex: 2
}]
});
|
上面代码输出:
这个布局容许你渲染一个表格出来。你能够指定列数和行数,使用 rowspan 和 colspan 建立复杂布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout:{
type: 'table',
columns: 3,
tableAttrs: {
style: {
width: '100%'
}
}
},
items: [{
rowspan: 3,
title: 'Item 1',
html: 'Item 1'
},{
title: 'Item 2',
html: 'Item 2'
},{
title: 'Item 3',
rowspan: 2,
html: 'Item 3'
},{
title: 'Item 4',
html: 'Item 4'
},{
title: 'Item 5',
html: 'Item 5'
},{
title: 'Item 6',
html: 'Item 6'
},{
title: 'Item 7',
html: 'Item 7'
}]
});
|
如下截图所示为前面 table 布局代码的输出结果:
这个布局内,子组件是垂直向下一个接一个排列。看一下如下的示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 700,
height: 400,
layout:{
type: 'vbox',
pack: 'start',
align: 'stretch',
},
items: [{
title: 'Item 1',
html: 'Item 1',
flex: 1
},{
title: 'Item 2',
html: 'Item 2',
height: 100
},{
title: 'Item 3',
html: 'Item 3',
flex: 2
}]
});
|
这段代码所示的输出:
在本章中,咱们了解学习了在 Ext JS 中的基础类和这些类中经常使用的方法,你还学习了如何建立和扩展一个类。还有如何使用 事件 和 查询元素及组件的功能。