javascript
Ext JS 6学习文档-第3章-基础组件
Ext JS 6學習文檔-第3章-基礎組件
基礎組件
在本章中,你將學習到一些 Ext JS 基礎組件的使用。同時我們會結合所學創建一個小項目。這一章我們將學習以下知識點:
- 熟悉基本的組件 – 按鈕,文本框,日期選擇器等等
- 表單字段的校驗
- 菜單和工具欄
- 設計一個表單
- 計算器程序– 本章的示例項目
本章的主要目的是創建一個表單設計和一個計算器示例項目。以下圖分別展示了表單設計和計算器設計。
首先,你觀察下列表單設計,你會發現我們使用了大量的控件,例如 label 和文本框。
以下圖展示了表單的設計:
?
繼續,設計計算器程序大量的使用了按鈕控件。所以你首要學習的是按鈕和 handler 。隨后在本章最后我們將會構建一個 計算器程序。在這個過程中,你會知道如何使 view(視圖) 和 controller(控制器)進行交互并協同工作。我們還將看到如何綁定 view model(視圖模型) 的屬性到一個 view(視圖) 的字段上。
下圖為計算機的設計展示:
熟悉基本組件
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'); ????} }); |
前面代碼的輸出:
?
我在第二章已經介紹過如何運行樣例代碼,但這里我還想再次重申這一點,此文檔中的大部分樣例代碼都是可以直接運行的。你可以選擇在你本地設備上或者在 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 ????} }); |
?
在即將到來的章節中你將學習更多關于 模型,視圖模型,字段,字段類型,校驗 等等。
總結
在本章中,你了解了不同的基本組件,例如 文本框,數字框,按鈕,菜單等等。你已經學會如何使用表單字段設計一個表單和我們之前創建了一個簡單的計算器項目。
轉載于:https://www.cnblogs.com/hq2008/p/5804629.html
總結
以上是生活随笔為你收集整理的Ext JS 6学习文档-第3章-基础组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【有美女看】提升用户体验,你不得不知道的
- 下一篇: react 不能往组件中传入属性的值为