前言
大型用戶端應用程式總是很難編寫,很難組織和很難維護。隨著功能的增加和更多的開發人員加入項目,對項目的控制也越來越困難了。Ext JS 4 提供了一個新的應用程式架構協助組織代碼。
模型 - 一組欄位和資料的集合。Model (在Ext JS 3中使用Record class)
視圖 - 組件類型, grids,trees 和 panels 都是屬於試圖
控制器 -- 用來渲染試圖,執行個體模型和其他的應用邏輯
檔案結構
Ext JS4 遵循統一的目錄結構。看一個例子:
index.html 的內容大致如下:
<html><head> <title>Account Manager</title> <link rel="stylesheet" type="text/css" href="ext-4.0/resources/css/ext-all.css"> <script type="text/javascript" src="ext-4.0/ext-debug.js"></script> <script type="text/javascript" src="app.js"></script></head><body></body></html>
在app.js 中建立應用
每一個Ext JS 4的應用都從建立一個Application 類的執行個體開始。這個Application執行個體裡配置了一些全域的設定(比如應用的名字)和模型,試圖和控制器的設定。一個application也包含了一個啟動的函數。
這裡以一個簡單的帳號管理應用為例,
首先,定義一個全域命名空間。所有的Ext JS應用都應該使用一個全域命名空間,所有的應用的類都位於這個之下。這裡以 “AM”為例。
Ext.application({ name: 'AM', appFolder: 'app', launch: function() { Ext.create('Ext.container.Viewport', { layout: 'fit', items: [ { xtype: 'panel', title: 'Users', html : 'List of users will go here' } ] }); }});
定義一個控制器
控制器是把應用程式串連在一起的膠水。它們監聽事件(從視圖中過來)並執行一些操作。繼續上面的例子,建立一個控制器。
app/controller/Users.js
Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', init: function() { console.log('Initialized Users! This happens before the Application launch function is called'); }});
然後,把這個控制器加到應用中(app.js)
Ext.application({ ... controllers: [ 'Users' ], ...});
當在瀏覽器中訪問index.html的時候,Users這個控制器會自動被載入,它的init 函數會在應用的lanch 函數執行之前被調用。
init 函數用來設定和試圖互動的控制器,以及和其他的控制器的關聯。 control 函數可以很容易的監聽事件並執行相應的動作處理函數。完善上面的Users 控制器
Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', init: function() { this.control({ 'viewport > panel': { render: this.onPanelRendered } }); }, onPanelRendered: function() { console.log('The panel was rendered'); }});
這裡在init 函數裡使用了 this.control 來監聽視圖的事件。control 函數使用了最新的 ComponentQuery 引擎來快速找到引用的組件。關於ComponentQuery 可以參考ComponentQuery documentation。
啟動並執行效果如下:
定義一個視圖
試圖無非就是組件,這裡建立一個Users grid 定義在檔案app/view/user/List.js 中
Ext.define('AM.view.user.List' ,{ extend: 'Ext.grid.Panel', alias : 'widget.userlist', title : 'All Users', initComponent: function() { this.store = { fields: ['name', 'email'], data : [ {name: 'Ed', email: 'ed@sencha.com'}, {name: 'Tommy', email: 'tommy@sencha.com'} ] }; this.columns = [ {header: 'Name', dataIndex: 'name', flex: 1}, {header: 'Email', dataIndex: 'email', flex: 1} ]; this.callParent(arguments); }});
接下來,就是把這個視圖加到Users控制器中。
Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', views: [ 'user.List' ], init: ... onPanelRendered: ...});
接著就是放入到app.js中的 viewport中
Ext.application({ ... launch: function() { Ext.create('Ext.container.Viewport', { layout: 'fit', items: { xtype: 'userlist' } }); }});
這裡使用xtype 指定userlist, (使用動態匯入), 呈現的效果如下:
控制網格
這裡添加每行的雙擊事件:
Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', views: [ 'user.List' ], init: function() { this.control({ 'userlist': { itemdblclick: this.editUser } }); }, editUser: function(grid, record) { console.log('Double clicked on ' + record.get('name')); }});
效果如下:
這裡edit 只是簡單的輸出log, 以下給出一個複雜的編輯函數,定義 edit 在app/view/user/Edit.js:
Ext.define('AM.view.user.Edit', { extend: 'Ext.window.Window', alias : 'widget.useredit', title : 'Edit User', layout: 'fit', autoShow: true, initComponent: function() { this.items = [ { xtype: 'form', items: [ { xtype: 'textfield', name : 'name', fieldLabel: 'Name' }, { xtype: 'textfield', name : 'email', fieldLabel: 'Email' } ] } ]; this.buttons = [ { text: 'Save', action: 'save' }, { text: 'Cancel', scope: this, handler: this.close } ]; this.callParent(arguments); }});
接下來,加入控制器中:
Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', views: [ 'user.List', 'user.Edit' ], init: ... editUser: function(grid, record) { var view = Ext.widget('useredit'); view.down('form').loadRecord(record); }});
實現效果如下:
建立Model 和 Store
建立 app/store/Users.js
Ext.define('AM.store.Users', { extend: 'Ext.data.Store', fields: ['name', 'email'], data: [ {name: 'Ed', email: 'ed@sencha.com'}, {name: 'Tommy', email: 'tommy@sencha.com'} ]});
接下來讓Controller 使用這個 Store
Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', stores: [ 'Users' ], ...});
更新app/view/user/List.js
Ext.define('AM.view.user.List' ,{ extend: 'Ext.grid.Panel', alias : 'widget.userlist', //we no longer define the Users store in the `initComponent` method store: 'Users', ...});