Ext JS 6学习文档-第3章-基础组件

时间:2021-09-03 22:06:35

Ext JS 6学习文档-第3章-基础组件

基础组件

在本章中,你将学习到一些 Ext JS 基础组件的使用。同时我们会结合所学创建一个小项目。这一章我们将学习以下知识点:

  • 熟悉基本的组件 – 按钮,文本框,日期选择器等等
  • 表单字段的校验
  • 菜单和工具栏
  • 设计一个表单
  • 计算器程序– 本章的示例项目

本章的主要目的是创建一个表单设计和一个计算器示例项目。以下图分别展示了表单设计和计算器设计。

首先,你观察下列表单设计,你会发现我们使用了大量的控件,例如 label 和文本框。

以下图展示了表单的设计:

Ext JS 6学习文档-第3章-基础组件

继续,设计计算器程序大量的使用了按钮控件。所以你首要学习的是按钮和 handler 。随后在本章最后我们将会构建一个 计算器程序。在这个过程中,你会知道如何使 view(视图) 和 controller(控制器)进行交互并协同工作。我们还将看到如何绑定 view model(视图模型) 的属性到一个 view(视图) 的字段上。

下图为计算机的设计展示:

Ext JS 6学习文档-第3章-基础组件

熟悉基本组件

Ext JS 有大量的优秀的控件,现在让我们开始认识这些基础的组件吧。

Ext.Button

这是一个很常用的控件;handler 是用于处理单击事件,如以下代码所示:

 
 
1
2
3
4
5
6
7
Ext.create('Ext.Button', {  
    text: 'My Button',  
    renderTo: Ext.getBody(),  
    handler: function() {    
        alert('click');
    }
});

前面代码的输出:

Ext JS 6学习文档-第3章-基础组件

 

我在第二章已经介绍过如何运行样例代码,但这里我还想再次重申这一点,此文档中的大部分样例代码都是可以直接运行的。你可以选择在你本地设备上或者在 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!');
    }
}) ;

现在粘贴下列的创建按钮的样例代码,运行并查看结果:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
Ext.application({  
    name : 'Fiddle',  
    launch : function() {
        Ext.create('Ext.Button', {      
            text: 'My Button',      
            renderTo: Ext.getBody(),      
            handler: function() {        
                alert('click');
            }
        });
    }
});
  • 不是所有的代码都可以这样运行,此外并非所有的示例代码都会有视觉呈现。

你还可以使用 listeners 配置添加更多的事件处理器,如以下代码所示:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ext.create('Ext.Button', {  
    text: 'My Button',  
    renderTo: Ext.getBody(),  
    listeners: {    
        click: {      
            fn: function(){
                //Handle click event        
                alert('click');
            }
        },
        mouseout: {      
            fn: function(){
                //Handle double click event        
                alert('Mouse out');
             }
        }
    }
});

以上代码只是创建了一个简单的按钮,你还可以创建很多不同的按钮,有 link button(连接按钮),menu button(菜单按钮),toggle button(开关按钮) 等等;

来创建一个链接按钮,设置 href 属性,如以下代码所示:

 
 
1
2
3
4
5
Ext.create('Ext.Button', {  
    renderTo: Ext.getBody(),  
    text: 'Link Button',  
    href: 'http://www.sencha.com/'
});

上面创建的链接按钮输出如图。当点击它则打开链接:

Ext JS 6学习文档-第3章-基础组件

通过设置 menu 属性,创建一个菜单按钮,如以下代码所示:

 
 
1
2
3
4
5
6
7
8
9
10
11
Ext.create('Ext.Button', {  
    text: 'My Button',  
    renderTo: Ext.getBody(),  
    menu: [{    
        text: 'Item 1'
    }, {    
        text: 'Item 2'
    }, {    
        text: 'Item 3'
    }]
});

输出如下,当点击时出现下拉菜单:

Ext JS 6学习文档-第3章-基础组件

Ext JS 6学习文档-第3章-基础组件

Ext.Button 还有许多属性,例如 bind, cls, disabledhtmltooltiptpl 等等,你可以根据自己需求使用。

Ext.MessageBox

Ext.window.MessageBox 类提供了 message box 实现。Ext. MessageBox 是一个单例对象。你可以使用 MessageBox 弹出一个警告,信息确认,提示输入等等。

下列代码将弹出一个简单的提示信息。这里解释一下 Ext.Msg 是 Ext. Messagebox 类的别名:

 
 
1
Ext.Msg.alert('Info', 'Document saved!');

下列代码将弹出一个消息确认框,button 为选择的值,取 yes 或 no :

 
 
1
2
3
4
5
6
7
Ext.Msg.confirm('Confirm', 'Are you want to cancel the updates?', function(button){  
    if('yes'==button) {
 
    }   else {
 
    }
});

你也可以自定义这个 message box 如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
Ext.MessageBox.show({  
    title:'Save Changes?',  
    msg: 'Do you want to save the file?',  
    buttons: Ext.MessageBox.YESNO,  
    fn: function(button){    
        if('yes'==button){
 
        }else if('no'==button){
 
        }  
    },
    icon: Ext.MessageBox.QUESTION
}) ;

上面代码输出如下:

Ext JS 6学习文档-第3章-基础组件

表单和表单字段

现在我们看一下都有哪些表单相关的组件。

Ext.form.Panel

这个 form panel (表单面板)继承自 panel  并添加了表单相关的功能,例如字段管理,校验,提交等等。form panel 的默认布局是 anchor layout ,但是如果需要你可以改变这个配置。

form panel 有一个很方便的配置为 fieldDefaults,它可以用于指定表单内所有字段的默认类型。

fields (字段/表单域)

Ext JS 提供了很多内置的表单字段。比较常用的一些字段:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Ext.form.field.Checkbox
 
Ext.form.field.ComboBox
 
Ext.form.field.Date
 
Ext.form.field.File
 
Ext.form.field.Hidden
 
Ext.form.field.HtmlEditor
 
Ext.form.field.Number
 
Ext.form.field.Radio
 
Ext.form.field.Text
 
Ext.form.field.TextArea
 
Ext.form.field.Time

我们看一下其中的一些字段的应用。

Ext.form.field.Text

这是一个基本的文本框,它具有很多有用的属性和配置。其中有一个很有用的属性是 vtype 它是用于校验的。 例如以下代码,这个 vtype 属性为 email 用于验证输入内容是否是有效的电子邮箱:

 
 
1
2
3
4
5
6
7
Ext.create('Ext.form.field.Text', {  
    renderTo: Ext.getBody(),  
    name: 'email',  
    fieldLabel: 'Email',  
    allowBlank: false,  
    vtype: 'email'
});

这里 allowBlank 也是一个校验属性。通过设置 allowBlank 属性为 false ,如果这个字段为空白,将会提示校验不通过。

Ext.form.field.Number

number 字段继承自 spinner 字段,spinner 字段则继承自 text 字段,进而的 number 等于是继承了两者。这个 number 字段提供了几个选项来处理数值。下列代码创建了一个数值文本框:

 
 
1
2
3
4
5
6
7
8
Ext.create('Ext.form.field.Number', {  
    renderTo: Ext.getBody(),  
    name: 'Count',  
    fieldLabel: 'Count',
    value: 0,  
    maxValue: 10,  
    minValue: 0
});

Ext JS 6学习文档-第3章-基础组件

你可以移除下拉按钮,方向键,鼠标滚轮监听,用配置:hideTrigger, keyNavEnabled,和 mouseWheelEnabled 。

Ext.form.field.ComboBox

下列代码创建了一个月份下拉菜单。这个 combobox 有一个配置为 store。 这个 store 是数据源,为此下拉菜单提供数据。store 是属于 ExtJS 中数据包部分, 在接下来的章节中我们会详细介绍的。

combobox 中另一个重要的配置是 queryMode 。这个属性取值可以是 ‘local’ 或者 ‘remote’。如果你设置为 remote 了,那么这个数据源 store 将在运行加载数据时发送请求从远程服务器获取数据:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var months = Ext.create('Ext.data.Store', {
    fields: ['abbr', 'name'],
    data: [{"abbr":"JAN", "name":"January"},
        {"abbr":"FEB", "name":"February"},  
        {"abbr":"MAR", "name":"March"},
        {"abbr":"APR", "name":"April"},  
        {"abbr":"MAY", "name":"May"},
        {"abbr":"JUN", "name":"June"},  
        {"abbr":"JUL", "name":"July"},
        {"abbr":"AUG", "name":"August"},
        {"abbr":"SEP", "name":"September"},  
        {"abbr":"OCT", "name":"October"},
        {"abbr":"NOV", "name":"November"},
        {"abbr":"DEC", "name":"December"}]
}) ;
 
Ext.create('Ext.form.ComboBox', {  
    fieldLabel: 'Choose Month',
    store: months,  
    queryMode: 'local',  
    displayField: 'name',
    valueField: 'abbr',  
    renderTo: Ext.getBody()
});

以上代码的输出如下:

Ext JS 6学习文档-第3章-基础组件

Ext.form.field.HtmlEditor

Ext JS 也有一个非常优秀的 HTML 编辑器,它提供直接在 web 页面上处理文字的能力,如以下代码所示:

 
 
1
2
3
4
5
Ext.create('Ext.form.HtmlEditor', {  
    width: 800,  
    height: 200,  
    renderTo: Ext.getBody()
});

以上代码输出如下:

 Ext JS 6学习文档-第3章-基础组件

表单字段的校验

大多数表单都有自己的校验规则,例如你键入了一个非数值的内容到 number 字段,它将显示一个验证无效的提示。再有这个 text 字段(文本框) 校验属性有  allowBlankminLength,和 maxLength 。 更进一步的,还有 regex 属性可以使用正则表达式自定义校验。

form panel 的事件

form panel 支持的部分事件:

  • beforeaction: 任意动作执行前触发,例如 submit,load,doAction 这些动作执行时
  • actionfailed: 执行一个动作失败时触发
  • actioncomplete: 在一个动作执行完成之后触发This event will be fired after an action is completed
  • validitychange: 表单键入的内容有效性发生变化时触发
  • dirtychange: 表单的dirty状态改变时触发

表单字段容器

以下是一些 from panel 里很有用的容器。

Ext.form.CheckboxGroup

CheckboxGroup 继承自 FieldContainer 用于组织复选框。下列示例中,复选框组的 items 中所有的项都有相同的 name ;这有助于将得到的值作为一个单一的参数传递给服务器。

 
 
1
2
3
4
5
6
7
8
9
10
Ext.create('Ext.form.CheckboxGroup', {  
    renderTo: Ext.getBody(),  
    fieldLabel: 'Skills ',  
    vertical: true,  
    columns: 1,  
    items: [{ boxLabel: 'C++', name: 'rb', inputValue: '1' },
        { boxLabel: '.Net Framework', name: 'rb', inputValue: '2', checked: true },
        { boxLabel: 'C#', name: 'rb', inputValue: '3' },
        { boxLabel: 'SQL Server', name: 'rb', inputValue: '4' }]
}) ;

以上代码输出如下:

Ext JS 6学习文档-第3章-基础组件

Ext.form.FieldContainer

FieldContainer 是很有用的,当你想将一组相关字段附加到一个标签时。

以下代码的输出你会发现一个 label 后面绑定了两个文本框:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Ext.create('Ext.form.FieldContainer', {
    renderTo: Ext.getBody(),
    fieldLabel: 'Name',  
    layout: 'hbox',  
    combineErrors: true,  
    defaultType: 'textfield',
    defaults: {    
        hideLabel: 'true'
    },  
    items: [{
        name: 'firstName',
        fieldLabel: 'First Name',
        flex: 2,    
        emptyText: 'First',    
        allowBlank: false
    }, {    
        name: 'lastName',    
        fieldLabel: 'Last Name',
        flex: 3,    
        margin: '0 0 0 6',    
        emptyText: 'Last',    
        allowBlank: false
    }]
});

Ext JS 6学习文档-第3章-基础组件

 

Ext.form.RadioGroup

RadioGroup 继承自 CheckboxGroup 用于组织单选按钮。items 中的项都有相同的 name,另外这是单选的,如以下代码所示:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Ext.create('Ext.form.RadioGroup', {  
    renderTo: Ext.getBody(),  
    fieldLabel: 'Sex ',  
    vertical: true,  
    columns: 1,  
    items: [{
        boxLabel: 'Male',
        name: 'rb',
        inputValue: '1'
    },{
        boxLabel: 'Female',
        name: 'rb',
        inputValue: '2'
    }]
});

代码输出:

Ext JS 6学习文档-第3章-基础组件

提交表单

使用 form 的 submit 方法提交表单。使用 getForm 方法获取表单并 isValid 方法进行提交前的表单内容校验。如以下代码所示:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var form = this.up('form').getForm();
if (form.isValid()) {  
    form.submit({    
        url: 'someurl',    
        success: function () {
 
        },
        failure: function () {
 
        }
    });
} else {
    Ext.Msg.alert('Error', 'Fix the errors in the form')
}

菜单和工具栏

对于你能想到的任何的菜单和工具栏 Ext JS 提供了最完整的支持。Ext.toolbar.Toolbar 用于构建一个工具栏。默认情况下任何子项在Ext.toolbar.Toolbar 都是按钮,但是你可以添加任意控件进去,例如一个文本框,一个数值框,一个图标,一个下拉菜单等等。

规范整理你的工具栏中的项,你可以使用 空格(Ext.toolbar.Spacer), 分隔符(Ext.toolbar. Separator),和 使控件右对齐(Ext.toolbar.Fill) 。这里也可以使用快捷方式  ‘ ‘ (空格),’-‘ 和 ‘|’ (都是分隔符,只有很小的差别),和 ‘->‘ (右对齐)。

Ext.menu.Menu 用于构建一个菜单,items 属性中为 Ext.menu.Item 一个个菜单项。

一个简单的代码示例和以下截图的输出:

Ext JS 6学习文档-第3章-基础组件

 
 
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
44
45
46
Ext.create('Ext.toolbar.Toolbar', {  
    renderTo: Ext.getBody(),
    width: 800,   items: [{
        text: 'My Button'
    },{
        text: 'My Button',    
        menu: [{      
            text: 'Item 1'
        }, {
            text: 'Item 2'
        }, {
            text: 'Item 3'
        }]
    },{
            text: 'Menu with divider',    
            tooltip: {
                text: 'Tooltip info',      
                title: 'Tip Title'
            },    
            menu: {      
                items: [{        
                    text: 'Task 1',
                    // handler: onItemClick
                }, '-', {
                    text: 'Task 2',
                    // handler: onItemClick
                }, {
                    text: 'Task 3',
                    // handler: onItemClick
                }]
            }
   },'->',{
       xtype: 'textfield',    
        name: 'field1',
       emptyText: 'search web site'
   },'-','Some Info',{
       xtype: 'tbspacer'
   },{    
        name: 'Count',    
        xtype: 'numberfield',    
        value: 0,    
        maxValue: 10,    
        minValue: 0,    
        width: 60
   }]
});

设计一个(客户反馈)表单

现在根据之前所学,我们来设计一个表单。

我们将设计如图所示的表单:

Ext JS 6学习文档-第3章-基础组件

以下是这个表单的代码。这里我维护着一个这个例子的完整的源码 https://github.com/ananddayalan/extjs-by-example-customer-feedback-form

这里我们所有的组件都在 Viewport 中。 这是一个专用的容器,它代表浏览器里应用的视图区域。

在 Viewport 中我们设置 scrollable 选项将子组件设为滚动的,使用 true 或 false 。也可以取值为 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
Ext.create('Ext.container.Viewport', {
scrollable: true,  
items: [{    
xtype: 'container',    
layout: {  
type: 'hbox',  
align: 'center',  
pack: 'center'
},    
items: [ {      
xtype: 'form',      
bodyPadding: 20,      
maxWidth: 700,      
flex: 1,
title: 'Custom Feedback',
items:[{
xtype: 'fieldcontainer',        
layout: 'hbox',        
fieldLabel: 'Name',        
defaultType: 'textfield',
defaults: {          
allowBlank: false,          
flex: 1
},
items: [{          
name: 'firstName',          
emptyText: 'First Name
}, {          
name: 'lastName',          
margin: '0 0 0 5',          
emptyText: 'Last Name'
}]
},{        
xtype: 'datefield',        
fieldLabel: 'Date of Birth',
name: 'dob',        
maxValue: new Date() /* Prevent entering the future date.*/
}, {
fieldLabel: 'Email Address',        
name: 'email',
vtype: 'email',
allowBlank: false
}, {
fieldLabel: 'Phone Number',        
labelWidth: 100,
name: 'phone',
width: 200,
emptyText: 'xxx-xxx-xxxx',
maskRe: /[\d\-]/,        
regex: /^\d{3}-\d{3}-\d{4}$/,
regexText: 'The format must be xxx-xxx-xxxx'
},{
xtype: 'radiogroup',
fieldLabel: 'How satisfied with our service?',
vertical: true,
columns: 1,
items: [ {          
boxLabel: 'Very satisfied',
name: 'rb',          
inputValue: '1'
}, {
boxLabel: 'Satisfied',          
name: 'rb', inputValue: '2'
}]      
},{
xtype: 'checkboxgroup',
fieldLabel: 'Which of these words would you use to describe our products? Select all that apply',
vertical: true,        
columns: 1,        
items: [{          
boxLabel: 'Reliable',          
name: 'ch',          
inputValue: '1'
}]
},{
xtype: 'radiogroup',
fieldLabel: 'How likely is it that you would recommend this company to a friend or colleague?',
vertical: false,        
defaults: { padding: 20 },
items: [ {          
boxLabel: '1',          
name: 'recommend',          
inputValue: '1'
}],        
buttons: [{
text: 'Submit',          
handler: function () {
var form = this.up('form').getForm();
if (form.isValid()) {              
form.submit({                
url: 'cutomer/feedback',                
success: function () {},                
failure: function () {}
});
} else {
Ext.Msg.alert('Error', 'Fix the errors in the form')
}
}
}]
}]
}]
}]
});

在以上代码中通过在容器级设置 defaultType 属性,这样我们就可以不必在容器的每个子组件里重复的指定 xtype 属性了。这样默认情况下,所有子组件在没有显式指定 xtype 时默认的类型都是 textfield 。

form panel 上有一个 flex 配置用于填补父容器的宽度,同时通过设置 maxWidth 为 700 限制 form panel 的最大宽度。

字段容器使用 hbox 布局将 first name 和 last name 文本框放在一个 label 标签下。

写一个计算器应用

现在我们结合目前所学构建一个完整的小项目。这是我们将要构建的计算器的设计:

 Ext JS 6学习文档-第3章-基础组件

文件夹结构

这是我们创建的计算器工程的目录结构。这里我不是用 sencha Cmd 生成的项目,只是从 Ext JS 复制了一些必须的文件到项目文件夹中:

Ext JS 6学习文档-第3章-基础组件

完整可用的项目在这里: https://github.com/ananddayalan/extjs-by-example-calculator.

App – app.js

在 app.js 文件里我们简单的创建了 Main 视图,作为可移动窗体浮动在浏览器:

 
 
1
2
3
4
5
6
Ext.application({  
    name: 'Calc',  
    launch: function () {
        Ext.create('Calc.view.main.Main').show();
    }
});

再谈 MVC 和 MVVM

第一章的时候,我们已经介绍过 MVC (Model View Controller) 和 MVVM (Model View ViewModel)。 这个示例项目的代码很好的展示了 视图,控制器,和视图模型之间的区别。

Model (模型)

这代表着数据层。model 保存的数据可以包含数据验证和逻辑。

View (视图)

这一层是用户界面。包含有 button,form,和 message box 等等组件。在我们这次写的计算器应用中 main.js 就是一个很好的视图例子。

Controller (控制器)

控制器处理 view(视图)相关的逻辑,例如 view 的 event(事件)处理,还有任何程序相关逻辑都可以写在这里。

ViewController (视图控制器) 和 Controller (控制器)

在 Ext JS 5 和 6 中,有两种类型的控制器:ViewController 和 Controller。 这个 ViewController 自 Ext JS 5 开始引进的。ViewController 是为一个指定的视图创建的控制器,但是这个控制器也可以交叉其他视图的逻辑。

ViewController 带来了一些新的概念,例如 引用和监听,简化视图与控制之间的关系。同时 View 销毁时 ViewController 也会被销毁,他们具有相同的生命周期,在这个例子中我们没有使用 引用和监听,但是在下一个例子中我们会使用的。

  • 你可以使用 listeners  代替 handler 处理事件

 

View model

view model 封装了 view(视图)所需要的展示逻辑,绑定数据到 view 并且每当数据改变时处理更新。

它有别于 model ,view model 主要是为一个指定的视图而创建的。一个 model 是一个纯粹的数据类并可用于整个应用中,但一个 view model 是起到一个 view 和 model 之间的数据粘合剂的作用。看一下 main.js 的 视图模型绑定。

视图 — Main.js

这里我为这个计算器应用创建一个视图为 Main 。这个视图里包含所有的按钮,显示字段等等。相关的事件用 controller 的方法。这个视图的控制器已经使用 controller 配置指定了。

这个视图使用 table 布局,配置为 4 列。CSS 类使用 cls 属性指定。

代码里有附加的注释:

 
 
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
Ext.define('Calc.view.main.Main', {  
extend: 'Ext.window.Window',
/* 表示在当前视图加载之前先加载这些所需的类*/
requires: [ 'Calc.view.main.MainController',
            'Calc.view.main.MainModel'],  
xtype: 'app-main',  
controller: 'main',
/* 视图的 view model (视图模型)*/  
viewModel: { type: 'main' },
resizable: false,  
layout: {    
type: 'table',    
columns: 4
},  
/* defaultType 和 defaults 属性是用于 items 内的子组件的,任何子组件都可以覆盖这些配置 */
defaultType: 'button',  
defaults: {    
width: 50,
height: 50,    
cls: 'btn',    
handler: 'onClickNumber'
},  
/* 这里我用 Ext.window.Window 的 header 显示计算器的结果。使用 header 你可以在浏览器里移动这个计算器。*/
header: {    
items: [{
xtype: 'displayfield',      
colspan: 4,      
width: 200,      
cls: 'display',      
bind: {
value: '{display}'
},
height: 60,      
padding: 0
}]
},
items: [{    
text: 'C',    
colspan: 2,    
width: 100,    
cls: 'btn-green',    
handler: 'onClickClear'
}, {    
text: '+/-',    
cls: 'btn-green',    
handler: 'onClickChangeSign'
}, {    
text: '÷',    
cls: 'btn-orange',    
handler: 'onClickOp'
},{
text: '7'
},{
text: '8'
},{
text: '9'
},{
text: '×',    
cls: 'btn-orange',    
handler: 'onClickOp'
},{
text: '4'
},{
text: '5'
},{
text: '6'
},{
text: '-',    
cls: 'btn-orange',    
handler: 'onClickOp'
},{
text: '1'
},{
text: '2'
},{
text: '3'
},{
text: '+',    
cls: 'btn-orange',    
handler: 'onClickOp'
},{
text: '0',    
width: 100,    
colspan: 2
},{
text: '.',    
handler: 'onClickDot'
},{
text: '=',    
cls: 'btn-orange',    
handler: 'onClickOp'
}]
});

控制器 — MainController.js

虽然这个控制器的代码有点长,这是一个非常简单的代码。控制器中有很多方法处理按钮的点击事件,例如运算符和操作数的点击处理。控制器使用了一个 model 为 Main :

 
 
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Ext.define('Calc.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',  
views: ['Calc.view.main.Main'],
models: ['Main'],
//这个 state 是一个自定义属性,用来跟踪计算器的状态。
        state: {
            operatorClicked: false,    
            selectedOperator: null,    
            dotClicked: false,
            op1: 0,    
            numberClicked: false,    
            sign: true,    
            decimal: false
        },
onClickClear: function () {
var vm = this.getViewModel();    
vm.set('display','0');    
this.state.selectedOperator=null;
this.state.op1=0;    
this.state.isPositive = true;    
this.state.decimal = false;    
this.state.sign = true;
},
onClickChangeSign: function (btn) {
var vm = this.getViewModel();    
var cur = vm.get('display');    
if(cur!='0') {      
if(this.state.sign===true ) {        
vm.set('display', '-' + cur);
}else {
vm.set('display', cur.toString().substring(1));
}
   }
   this.state.sign=!this.state.sign;
},
onClickOp: function (btn) {
if(this.state.selectedOperator!=null && this.state.numberClicked===true){
var vm = this.getViewModel();      
var op2 = parseFloat(vm.get('display'));      
var op1 = parseFloat(this.state.op1);
var result = 0;
switch(this.state.selectedOperator){        
case '+':        
result = op1 + op2;        
break;                
case '-':        
result = op1 - op2;
break;                
case '×':        
result = op1 * op2;        
break;                
case '÷':        
result = op1 / op2;        
break;
}
vm.set('display', Math.round(result * 100) / 100);
this.state.selectedOperator=null;
}    
if(btn.text!='=') {
this.state.operatorClicked = true;
}
this.state.selectedOperator = btn.text;    
this.state.numberClicked = false;
},
onClickDot: function (btn) {    
if(this.state.decimal===false) {      
var vm = this.getViewModel();      
vm.set('display', vm.get('display') + '.');
}
},
onClickNumber: function (btn) {
this.state.numberClicked = true;    
if(this.state.selectedOperator ==='='){
this.onClickClear();
}
var vm = this.getViewModel();    
if(this.state.operatorClicked===true) {      
this.state.op1= vm.get('display');      
vm.set('display', btn.text);      
this.state.operatorClicked=false;
}else{
var cur = vm.get('display');      
if(cur == '0') {        
cur = '';
}
vm.set('display', cur + btn.text);
}  
}
});

 

视图模型 — MainViewModel.js

这个 ViewModel 只有一个属性为 display 。这个用来绑定到计算器显示的值上。这里我们不会分别用一组字段创建模型,此外我们还将会硬编码数据。

 
 
1
2
3
4
5
6
7
Ext.define('Calc.view.main.MainModel', {  
    extend: 'Ext.app.ViewModel',  
    alias: 'viewmodel.main',  
    data: {    
        display: 0.0
    }
});

在即将到来的章节中你将学习更多关于 模型,视图模型,字段,字段类型,校验 等等。

总结

在本章中,你了解了不同的基本组件,例如 文本框,数字框,按钮,菜单等等。你已经学会如何使用表单字段设计一个表单和我们之前创建了一个简单的计算器项目。

Ext JS 6学习文档-第3章-基础组件的更多相关文章

  1. Ext JS 6学习文档-第6章-高级组件

    Ext JS 6学习文档-第6章-高级组件 高级组件 本章涵盖了高级组件,比如 tree 和 data view.它将为读者呈现一个示例项目为 图片浏览器,它使用 tree 和 data view 组 ...

  2. Ext JS 6学习文档-第5章-表格组件(grid)

    Ext JS 6学习文档-第5章-表格组件(grid) 使用 Grid 本章将探索 Ext JS 的高级组件 grid .还将使用它帮助读者建立一个功能齐全的公司目录.本章介绍下列几点主题: 基本的 ...

  3. Ext JS 6学习文档-第8章-主题和响应式设计

    Ext JS 6学习文档-第8章-主题和响应式设计 主题和响应式设计 本章重点在 ExtJS 应用的主题和响应式设计.主要有以下几点内容: SASS 介绍和入门 主题 响应式设计 SASS 介绍和入门 ...

  4. Ext JS 6学习文档-第7章-图表

    Ext JS 6学习文档-第7章-图表 使用图表 本章中将探索在 ExtJS 中使用不同类型的图表并使用一个名为费用分析的示例项目结束本章所学.以下是将要所学的内容: 图表类型 条形图 和 柱形图 图 ...

  5. Ext JS 6学习文档-第4章-数据包

    Ext JS 6学习文档-第4章-数据包 数据包 本章探索 Ext JS 中处理数据可用的工具以及服务器和客户端之间的通信.在本章结束时将写一个调用 RESTful 服务的例子.下面是本章的内容: 模 ...

  6. Ext JS 6学习文档–第1章–ExtJS入门指南

    Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的,因为 ExtJS 6 目前的中文学习资料还很少.google 搜索资料时找到了一本国外牛人写的关于 ExtJS ...

  7. Ext JS 6学习文档–第2章–核心概念

    核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目.这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS ...

  8. Sencha Cmd 6 和 Ext JS 6 指南文档(部分官方文档中文翻译)

    近期组织了几个程序员网友,正在翻译一部分官方的Sencha Cmd 6 和 Ext JS 6 指南文档. 眼下还没翻译完,大家能够先看看 Sencha Cmd 6 和 Ext JS 6 指南文档  ( ...

  9. Prism 4 文档 ---第3章 管理组件间的依赖关系

     基于Prism类库的应用程序可能是由多个松耦合的类型和服务组成的复杂应用程序,他们需要根据用户的动作发出内容和接收通知进行互动,由于他们是松耦合的,他们需要一种方式来互动和交流来传递业务功能的需求. ...

随机推荐

  1. Oracle Flashback Technologies - 闪回被drop的表

    Oracle Flashback Technologies - 闪回被drop的表 在oracle10g中,drop一个表后,表没有真正被删除,支持被rename后放在recyclebin中. #新建 ...

  2. 编译Linux系统下的jrtplib3.9和jthread1.3(arm和ubuntu)

    最近由于学习需要,需要编译jrtplib,网上的资料基本上都是关于3.9以前的版本,而以前的版本基本上都是通过confiugre来配置生成Makefile,而最近的版本却没有这一项,而是使用cmake ...

  3. C# IO流的操作

    C# IO流的操作非常重要,我们读写文件都会使用到这个技术,这里先演示一个文件内容复制的例子,简要说明C#中的IO操作. namespace ConsoleApplication1 { class P ...

  4. Flexigrid折行显示问题

    上会写的Flexigrid折行显示时,获取值有问题,报错. getRows: function(){ //add by jej var rtnList = new Array(); var objRo ...

  5. POJ2771_Guardian of Decency(二分图/最大独立集=N-最大匹配)

    解决报告 http://blog.csdn.net/juncoder/article/details/38159017 题目传送门 题意: 看到题目我就笑了.., 老师觉得这种两个学生不是一对: 身高 ...

  6. 【转载】Eclipse 断点调试

      作为开发人员,掌握开发环境下的调试技巧十分有必要.去年就想把关于Eclipse断点调试总结下了,由于对时间的掌控程度仍需极大提高,结果拖到今年才写了此篇博文.关于Java调试技术还有很多,如Jav ...

  7. Ubuntu常用软件安装(附带地址和卸载自带软件)

    跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 上次说了安装VSCode(http://www.cnblogs.com/dun ...

  8. 《算法导论》学习总结 — XX.第22章 图的基本算法

    BFS(广搜): 广搜就是广度优先搜索,根据名字可以知道,是通过广度来遍历图,也就是层次遍历吧. 在这里以及下面的DFS(深搜),都用到了颜色WHITE,GRAY,BLACK,不过作用不同,具体分别再 ...

  9. 使用echarts水球图

    使用echarts水球图 官方实例中没有水球图样式,当我们需要用到水球图的时候需要下载echarts-liquidfill.js. 使用 在echarts之后引入 echarts-liquidfill ...

  10. 首发福利!全球第一开源ERP Odoo系统架构部署指南 电子书分享

    引言 Odoo,以前叫OpenERP,是比利时Odoo S.A.公司开发的一个企业应用软件套件,开源套件包括一个企业应用快速开发平台,以及几千个Odoo及第三方开发的企业应用模块.Odoo适用于各种规 ...