對於Extjs來說,大客戶端程序一直很難寫,當你為大客戶端程序添加更多的功能和項目的時候,項目的體積往往迅速增長。這樣的大客戶端程序很難組織和維持 ,所以,Extjs4配備了一個新的應用程序體系結構,它能結構化你的代碼,那就是Extjs4 MVC。
Extjs4 MVC有別於其他MVC架構,Extjs有他自己定義:
1、Model是一個Field以及他的Data的集合,Modes知道如何通過Stores來表示數據,以能用於網格和其他組件。模型的工作很像Extjs3的記錄集(Record class),通常通過數據加載器(Stores)渲染至網格(grid)和其他組件上邊。
2、View:用以裝載任何類型的組件—grid、tree和panel等等。
3、Controller—用來放使得app工作的代碼,例如 render views , instantiating Models 或者其他應用邏輯。
本篇文章,我們將創建一個非常簡單的應用程序,即用戶數據管理,最后,你就會知道如何利用Extjs4 MVC去創建簡單應用程序。Extjs4 MVC應用程序架構提供應用程序的結構性和一致性。這樣的模式帶來了一些重要的好處:
1、 每個應用程序的工作方式相同,我們只需要學習一次。
2、 應用程序之間的代碼共享很容易,應為他們所有的工作方式都相同
3、 你可以使用EXTJS提供的構建工具創建你應用程序的優化版本。
既然是介紹Extjs4 MVC,那么,我們開始創建這個應用。
一、文件結構(File Structure):
Extjs4 MVC的應用程序和別的應用程序一樣都遵循一個統一的目錄結構。在MVC布局中,所有的類放在應用程序文件夾,它的子文件夾中包含您的命名空間,模型,視圖,控制器和存儲器。下面來通過簡單的例子來看下怎樣應用。
在這個例子中,我們將整個應用程序放到一個名為”account_manager”的文件夾下,”account_manager”文件夾中的結構如上圖。現在編輯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文件。
所有Extjs4 MVC應用從Ext.application的一個實例開始,應用程序中應包含全局設置、以及應用程序所使用的模型(model),視圖(view)和控制器(controllers),一個應用程序還應該包含一個發射功能(launch function)。
現在來創建一個簡單的賬戶管理應用。首先,需要選擇一個命名空間(所有extjs4應用應該使用一個單一的全局變來來作為命名空間)。暫時,使用”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'
- }
- ]
- });
- }
- });
以上代碼,做了如下幾件事。首先,調用Ext.application創建一個應用程序類的實例,設置了一個”AM”的命名空間,他將作為整個應用的全局變量,也將作為Ext.Loader的命名空間,然后通過appFolder來指定配置選項設置相應的路徑。最后,創建了一個簡單的發射功能,這里僅僅創建了一個Viewport,其中包含一個panel,使其充滿整個窗口。
三、定義一個控制器
控制器是整個應用程序的關鍵,他負責監聽事件,並對某些時間做出相應的動作。現在我們創建一個控制器,將其命名為Users.js,其路徑是app/controller/Users.js。然后,我們為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.js)自動加載,因為我們在上面的app.js中的定義中指定了。Init函數一個最棒的地方是控制器與視圖的交互,這里的交互是指控制功能,因為他很容易就可以監聽到視圖類的事件處理函數,並采取相應的措施,並及時渲染相關信息到面板上來。
編寫Users.js:
- 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');
- }
- });
在Users.js中,init函數使用this.control來負責監聽,由於使用了新的ComponentQuery引擎,所以可以快速方便的找到頁面上組件的引用(viewport > panel),這有些類似CSS選擇器,通過匹配,快速的找到相匹配的組件。
在上面的init函數中,我們使用viewport > panel,來找到app.js中Viewport下的panel組件,然后,我們提供了一個對象的處理函數(this. onPanelRendered,注意,這里的對象是this,他的處理函數是onPanelRendered)。整個效果是,只要符合觸發render事件的任何組件,那么onPanelRendered函數將被調用。當運行我們的應用程序,我們將看到以下內容。
四、定義一個視圖
到目前為止,應用程序只有幾行,也只有兩個文件,app.js和app/controller/Users.js。現在我們來增加一個grid,來顯示整個系統中的所有用戶。作為視圖組件的一個子類,我們創建一個新的文件,並把他放到app/view/user目錄下。命名為List.js。整個路徑是這樣的。app/view/user/List.js,下面,我們寫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);
- }});
我們創建好的這個類,只是一個非常普通的類,並沒有任何意義,為了能讓我們更好的使用這個定義好的類,所以我們使用alias來定義一個別名,這個時候,我們的類可以使用Ext.create()和Ext.widget()創建,在其他組件的子組件中,也可以使用xtype來創建。
- Ext.define('AM.controller.Users', {
- extend: 'Ext.app.Controller',
- views: [
- 'user.List'
- ],
- init: ... onPanelRendered: ...
- });
修改Users.js,增加views屬性,修改app.js中的launch方法,將List渲染到Viewport。
- Ext.application({
- ... launch: function() {
- Ext.create('Ext.container.Viewport', {
- layout: 'fit',
- items: {
- xtype: 'userlist'
- }
- });
- }});
看到這里,也許會有人開始抓狂了,這個user.List到底是怎么來的,為什么要這樣寫?如果你開始感到疑惑,那么不妨看看Ext.Loader是如何工作的(傳送門),在看過Ext.Loader之后,你就會明白了,User.List就是app/view/user下的List.js文件。為什么Ext要從view下找呢?因為我們在控制器中定了views: ['user.List']。這就是Extjs動態加載的強大之處,具體Ext.Loader,請看本站的其他文章,你就會明白了。當我們刷新頁面。
未完待續…