1、Extjs MVC開發模式
在JS的開發過程中,大規模的JS腳本難以組織和維護,這一直是困擾前端開發人員的頭等問題。Extjs為了解決這種問題,在Extjs4.x版本中引入了MVC開發模式,開始將一個JS(Extjs)應用程序分割成Model-View-Controller三層,為JS應用程序的如何組織代碼指明了方向,同時使得大規模JS代碼變得更加易於重用和維護;這就是Extjs MVC開發模式的初衷。
在官方給出的MVC例子中,我們可以看到一個簡單的列表編輯功能,這篇文章就圍繞這個功能進行詳細的講解,讓我們一起來揭開Extjs MVC的神秘面紗!
示例代碼適用於Extjs 4.x、Extjs 5.x和Extjs 6.0.1中親測可用!
建議1:編寫的所有JS、CSS、HTML/JSP統一編碼為UTF-8。
建議2:每個屬性之間必須使用逗號(非中文符號),最后一個屬性千萬不可以使用逗號。
2、創建一個Extjs MVC程序:
index.html
系統的首頁:加載樣式表、核心庫、app,js
app.js
命名空間、加載插件、指定app的主目錄、加載控制層、創建主視圖
app
Extjs程序的主程序文件夾
1)controller:所有的控制器
a)view:所有的視圖組件
b)store:所有的儲存數據源組件
c)model:所有的數據模型組件
2)其他自定義組件/工具:lib/util(可選,例如自定義全局校驗工具類、靜態數據)

2)每個應用都有一個實體,就是Application對象,而每個應用同樣采用單一入口結構,有個快捷函數就是 Ext.application({config}),創建一個Application對象實例,並且運行它。Application在創建之初,會去加 載Controller類,加載完畢后,會正式的lunch。
3)Application在lunch的時候,會創建一個Viewport實例,這個東西就像一個骨架一樣,上面可以拼裝各種View,具體說,就是各種布局形式和窗體控件,可以說是view界面的載體,一個頁面只能有一個Viewport實例。
4)View純粹是一個界面組件,或者說窗體控件的集合(比如form,grid和window)。通過Store來加載數據並且展現到界面上,界面控件的響應都寫在Controller里面,View對Controller的存在一無所知,也沒有代碼上的依賴
5)Controller的角色完全是個粘合劑,它在加載之初,會幫忙加載跟其有關的Model,Store,View類,而其真正的作用,是通過一系列的事 件處理函數(比如點擊保存按鈕),確定了每個View上面界面組件對用戶交互行為的響應方法,可以說是一堆事件處理器函數的集合;這里面主要通過一個 control成員函數來進行事件綁定,通過另一個叫ComponentQuery的組件,使用類似css selector的語法來定位界面上的組件,並為其綁定事件處理器。
6)Model是對抽象數據的具體化,簡單理解就是數據庫里面的一行記錄。
7)Store是對通過網絡加載數據的過程的一個抽象,Store通過data發送請求(一般為ajax請求)到后台獲取數據(一般返回json格式),Store依賴於Model,通過關聯的Model對象才知道如何將取回的數據對象化。
3、Extjs MVC程序的首頁
1)index.html Extjs開發環境的准備
功能:系統的首頁:加載樣式表、核心庫、app.js
官方的例子是自動根據環境加載extjs-theme-xxxx -all.css樣式表、extjs-all.js核心庫以及程序入口app,js。
<script type="text/javascript" src="../../shared/include-ext.js"></script> <script type="text/javascript" src="../../shared/options-toolbar.js"></script> <script type="text/javascript" src="all-classes.js"></script> <script type="text/javascript" src="app.js"></script>
官方提供了多套樣式模板:
ext-6.0.1\build\classic\theme-xxxx\resources
theme- xxxx -all.css需要運行環境
@import 'theme-classic-all_1.css';
@import 'theme-classic-all_2.css';
手工導入兩個css文件即可:
theme-xxxx-all_1.css theme-xxxx-all_2.css
設計自己的MVC例子時候,最好手工加載樣式表、核心庫:
index.html
<head> <!--1.手工導入Extjs CSS--> <link rel="stylesheet" type="text/css" href="resources/theme/ext-theme-neptune/build/resources/ext-theme-neptune-all_01.css" /> <link rel="stylesheet" type="text/css" href="resources/theme/ext-theme-neptune/build/resources/ext-theme-neptune-all_02.css" /> <!--2.手工導入Extjs Core JS--> <script type="text/javascript" charset="UTF-8" src="js/ext-all.js"></script> <!--3.app程序的入口--> <script type="text/javascript" src="app.js"></script> </head>
注意:需要拷貝ext-all.js和resources樣式文件夾到相對的目錄路徑
4、Extjs MVC的App.js介紹
每個應用都有一個實體,就是Application對象,而每個應用同樣采用單一入口結構,有個快捷函數就是Ext.application({config}),創建一個Application對象實例,並且運行它。Application在創建之初,會去加載Controller類,加載完畢后,會正式的lunch。
Application在lunch的時候,會創建一個Viewport實例,這個東西就像一個骨架一樣,上面可以拼裝各種View,具體說,就是各種布局形式和窗體控件,可以說是view界面的載體,一個頁面只能有一個Viewport實例。
1)Name屬性與命名空間
Ext.application({ name: 'FV', //指定程序的命名空間: });
name屬性用於指定程序命名空間(MVC組件)
例如controller文件夾內聲明一個控制器聲明規則:
Ext.define(命名空間.文件夾.文件名,{extend:'繼承類型',屬性1,屬性2......});
例如controller/Articles.js
Ext.define('FV.controller.Articles', {
extend: 'Ext.app.Controller', //必須繼承Controller
Controller組件屬性1:’’,
Controller組件屬性2:’’
});
如此類推:
model/Article.js文件
Ext.define('FV.model.Article', {
extend: 'Ext.data.Model',
Model組件屬性1:’’
});
store/Article.js文件
Ext.define('FV.store.Article', {
extend: 'Ext.data.Store',
Store組件屬性1:’’
});
view/article/Grid.js文件
Ext.define('FV.view.article.Grid', {
extend: 'Ext.grid.Panel',
Grid Panel'組件屬性:’’
});
view/article/Preview.js文件
Ext.define('FV.view.article.Preview', {
extend: 'Ext.panel.Panel',
Panel'組件屬性:’’
});
其實最好還是在命名JS文件的時候加上對應組件的后綴(模塊+組件):
controller/Articles.js controller/ArticlesController.js
model/Article.js model/ArticleModel.js
store/Article.js文件 store/ArticleStore.js文件
view/article/Grid.js文件 view/article/ArticleGrid.js文件
view/article/ Preview.js文件 view/article/ArticlePreview.js文件
2)app.js主程序詳細介紹
主程序:
a)定義程序命名前綴
b)定義主程序的文件夾路徑
c)定義程序需要加載控制層
d)初始化主視圖
Ext.application({ //1.Application命名前綴 name: 'Sys', //2.設置Application自定義classes的目錄路徑 paths: 'app', //3.加載controller文件夾下的 controller類(默認所有均初始化) controllers: [], /* launch: function() { alert("init之后 確保App初始化完成后執行,等價於onReady"); }, init: function() { alert("init"); },*/ //4.初始化主視圖(默認為paths/view/Viewport.js) autoCreateViewport: true });
name屬性:
用於指定程序命名空間(MVC組件),至關重要,在上面的例子已經詳細講述。
requires屬性:
有的時候項目中要寫一些擴展組件,隨着擴展組件的增加,會造成有的頁面需要使用,而有的頁面不需要使用的問題,這對組件的js文件的引用造成了煩惱:如果每個頁面都去引用的時候會造成瀏覽器打開頁面的流量的增加而影響資源,如果需要的時候引用管理起來又很麻煩,Extjs4.0幫我們解決了這個問題,那就是Ext.requires。它可以實現根據我們的需要動態加在所需要的組件文件,很靈活也很方便。requires屬性,在application程序中全局加載組件,動態的加載,只加載一次。
paths屬性:
不聲明:
app.js必須可以直接訪問到controller/model等JS文件夾相對路徑。
聲明:
a)直接指定加載JS路徑1:paths:'app'
去app文件夾下尋找controller/model等JS文件夾
b)直接指定命名空間+加載JS路徑2:paths:{'App.ux':'resources/ux'}
設置目錄映射'App.ux'命名空間的將去resources/ux下尋找
controller:[]屬性:
啟動App程序時加載所有的controller文件夾下的Controller組件並初始化。
如果程序比較大,建議動態根據模塊來加載和初始化Controller組件。以及對應Controller下配置的Model、Store、View組件
init: function() {}
初始化函數,application程序初始化的時候默認執行的方法,一般不需要聲明,也可以用於測試app.js是否成功初始化。
autoCreateViewport: true
自動創建application的OPOA視圖,默認加載並初始化app/view/Viewport.js
Ext.define('SYSTEM.view.Viewport', {
extend: 'Ext.container.Viewport',
requires: [],
layout: 'border',
items: []
});
VeiwPort 代表整個瀏覽器顯示區域,該對象渲染到頁面的body 區域,並會隨着瀏覽器顯示區域的大小自動改變,一個頁面中只能有一個ViewPort 實例。Viewport 不需要再指定renderTo,而我們也看到Viewport 確實填充了整個瀏覽器顯示區域,並會隨着瀏覽器顯示區域大小的改變而改變。Viewport 主要用於應用程序的主界面,可以通過使用不同的布局來搭建出不同風格的應用程序主界面。在Viewport 上常用的布局有fit、border 等,當然在需要的時候其它布局也會常用。
launch: function() {}
應用程序啟動init之后。這樣可以確保所有腳本加載,防止依賴問題。類似於Ext.onReady為DOM已經准備好了再執行邦定的特性。
實際用例:如application 的Viewport初始化之后才對其進行事件的邦定。
本文部分由齊飛(youring2@gmail.com)原創,並發布在http://www.qeefee.com/article/extjs-mvc-in-detail,轉載請注明出處!
