基礎組件html
在本章中,你將學習到一些 Ext JS 基礎組件的使用。同時咱們會結合所學建立一個小項目。這一章咱們將學習如下知識點:react
- 熟悉基本的組件 – 按鈕,文本框,日期選擇器等等
- 表單字段的校驗
- 菜單和工具欄
- 設計一個表單
- 計算器程序– 本章的示例項目
本章的主要目的是建立一個表單設計和一個計算器示例項目。如下圖分別展現了表單設計和計算器設計。git
首先,你觀察下列表單設計,你會發現咱們使用了大量的控件,例如 label 和文本框。github
如下圖展現了表單的設計:web
繼續,設計計算器程序大量的使用了按鈕控件。因此你首要學習的是按鈕和 handler 。隨後在本章最後咱們將會構建一個 計算器程序。在這個過程當中,你會知道如何使 view(視圖) 和 controller(控制器)進行交互並協同工做。咱們還將看到如何綁定 view model(視圖模型) 的屬性到一個 view(視圖) 的字段上。正則表達式
下圖爲計算機的設計展現:瀏覽器
熟悉基本組件
Ext JS 有大量的優秀的控件,如今讓咱們開始認識這些基礎的組件吧。服務器
Ext.Button
這是一個很經常使用的控件;handler 是用於處理單擊事件,如如下代碼所示:app
1
2
3
4
5
6
7
|
Ext.create('Ext.Button', {
text: 'My Button',
renderTo: Ext.getBody(),
handler: function() {
alert('click');
}
});
|
前面代碼的輸出:編輯器
我在第二章已經介紹過如何運行樣例代碼,但這裏我還想再次重申這一點,此文檔中的大部分樣例代碼都是能夠直接運行的。你能夠選擇在你本地設備上或者在 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/'
});
|
上面建立的連接按鈕輸出如圖。當點擊它則打開連接:
經過設置 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.Button 還有許多屬性,例如 bind, cls, disabled,html,tooltip,tpl 等等,你能夠根據本身需求使用。
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.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
});
|
你能夠移除下拉按鈕,方向鍵,鼠標滾輪監聽,用配置: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.form.field.HtmlEditor
Ext JS 也有一個很是優秀的 HTML 編輯器,它提供直接在 web 頁面上處理文字的能力,如如下代碼所示:
1
2
3
4
5
|
Ext.create('Ext.form.HtmlEditor', {
width: 800,
height: 200,
renderTo: Ext.getBody()
});
|
以上代碼輸出以下:
表單字段的校驗
大多數表單都有本身的校驗規則,例如你鍵入了一個非數值的內容到 number 字段,它將顯示一個驗證無效的提示。再有這個 text 字段(文本框) 校驗屬性有 allowBlank,minLength,和 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.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.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'
}]
});
|
代碼輸出:
提交表單
使用 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 一個個菜單項。
一個簡單的代碼示例和如下截圖的輸出:
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
}]
});
|
設計一個(客戶反饋)表單
如今根據以前所學,咱們來設計一個表單。
咱們將設計如圖所示的表單:
如下是這個表單的代碼。這裏我維護着一個這個例子的完整的源碼 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 標籤下。
寫一個計算器應用
如今咱們結合目前所學構建一個完整的小項目。這是咱們將要構建的計算器的設計:
文件夾結構
這是咱們建立的計算器工程的目錄結構。這裏我不是用 sencha Cmd 生成的項目,只是從 Ext JS 複製了一些必須的文件到項目文件夾中:
完整可用的項目在這裏: 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
}
});
|
在即將到來的章節中你將學習更多關於 模型,視圖模型,字段,字段類型,校驗 等等。
總結
在本章中,你瞭解了不一樣的基本組件,例如 文本框,數字框,按鈕,菜單等等。你已經學會如何使用表單字段設計一個表單和咱們以前建立了一個簡單的計算器項目。