組建和架構的包括固定的寫法,風格還有規範,經過一個栗子(僅包含一個grid和點擊事件),來描述extjs下的mvc和mvvm的總體結果javascript
<!DOCTYPE HTML> <html manifest=""> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="UTF-8"> <title>htjy</title> <link type="text/css" rel="stylesheet" href="css/font-awesome.css"> <!-- The line below must be kept intact for Sencha Cmd to build your application --> <script type="text/javascript" src="/ext/build/ext.js"></script> <script type="text/javascript" src="/ext/build/ext-all.js"></script> <script src="/ext/packages/ext-locale/build/ext-locale-zh_CN.js"></script> <link href="/ext/packages/ext-theme-crisp/build/resources/ext-theme-crisp-all.css" rel="stylesheet" /> </head> <body></body> <script> Ext.onReady(function() { //模型描述 Ext.define('User', { extend: 'Ext.data.Model', fields: [{ name: 'firstName', type: 'string' }, { name: 'lastName', type: 'string' }, { name: 'age', type: 'int' }, { name: 'eyeColor', type: 'string' }] }); //倉庫整合 Ext.define('UserStore', { extend: 'Ext.data.Store', model: "User", data: [{ firstName: 'Ed', lastName: 'Spencer' }, { firstName: 'Tommy', lastName: 'Maintz' }, { firstName: 'Aaron', lastName: 'Conran' }, { firstName: 'Jamie', lastName: 'Avins' }] }); var store = Ext.create('UserStore'); Ext.create('Ext.grid.Panel', { title: 'Simpsons', store: store, columns: [{ text: 'firstName', dataIndex: 'firstName' }, { text: 'lastName', dataIndex: 'lastName' }, { text: 'age', dataIndex: 'age' }, { text: 'eyeColor', dataIndex: 'eyeColor' }], listeners: { itemclick: function() { console.log('click el2'); } }, height: 200, width: 400, renderTo: Ext.getBody() }); }); </script> </html>
經過Sencha初始化+一個栗子的代碼,雖然這養完成了任務,但只用到了組建,尚未用到更爲重要的框架css
跟着網上的呆毛,不明覺厲的使用方式html
model:java
Ext.define('app.model.User', { extend: 'Ext.data.Model', fields: [{ name: 'firstName', type: 'string' }, { name: 'lastName', type: 'string' }, { name: 'age', type: 'int' }, { name: 'eyeColor', type: 'string' }] });
controller:json
Ext.define('app.controller.User', { extend: 'Ext.app.Controller', init: function() { this.control({ 'userlist': { itemclick: this.userlistHighlight } }); }, userlistHighlight: function() { console.log('click el'); } });
view:bootstrap
Ext.define("app.view.user.List", { extend: "Ext.grid.Panel", alias: 'widget.userlist', store: Ext.create('app.store.User'), columns: [{ text: 'firstName', dataIndex: 'firstName' }, { text: 'lastName', dataIndex: 'lastName' }, { text: 'age', dataIndex: 'age' }, { text: 'eyeColor', dataIndex: 'eyeColor' }] });
Viewport:單頁面入口架構
Ext.define("app.view.Viewport", { extend: "Ext.container.Viewport", layout: "fit", uses:['app.view.user.List','app.controller.User'], items: { xtype:"userlist" } });
Application:架構啓動mvc
Ext.define('app.Application', { extend: 'Ext.app.Application', name: 'app', stores: [ // TODO: add global / shared stores here ], controllers: ['User'], autoCreateViewport: true, launch: function() {} });
經過Sencha初始化+上面的代碼,就能夠正確的運行了,混合了配置信息和異步加載信息等多種方式,組建的使用錯誤不大,可是架構的使用,略微蛋疼app
一次性將全部js文件所有加載毫不是一個好主意,延遲加載/按需加載也就逐步轉換爲架構的一部分,而user與requires就是依賴元素(其中加載器中的require方法-.-畢竟乾的都是一件事)框架
requires:初始化依賴文件,
uses:業務(初始化後)依賴文件
createOverride: function (className, data, createdFn) { var me = this, overriddenClassName = data.override, requires = data.requires, uses = data.uses, mixins = data.mixins, mixinsIsArray, compat = data.compatibility, depedenciesLoaded, classReady = function () { var cls, dependencies, i, key, temp; if (!depedenciesLoaded) { dependencies = requires ? requires.slice(0) : []; if (mixins) { if (!(mixinsIsArray = mixins instanceof Array)) { for (key in mixins) { if (Ext.isString(cls = mixins[key])) { dependencies.push(cls); } } } else { for (i = 0, temp = mixins.length; i < temp; ++i) { if (Ext.isString(cls = mixins[i])) { dependencies.push(cls); } } } } depedenciesLoaded = true; if (dependencies.length) { // Since the override is going to be used (its target class is // now created), we need to fetch the required classes for the // override and call us back once they are loaded: Ext.require(dependencies, classReady); return; } // else we have no dependencies, so proceed } // transform mixin class names into class references, This // loop can handle both the array and object forms of // mixin definitions if (mixinsIsArray) { for (i = 0, temp = mixins.length; i < temp; ++i) { if (Ext.isString(cls = mixins[i])) { mixins[i] = Ext.ClassManager.get(cls); } } } else if (mixins) { for (key in mixins) { if (Ext.isString(cls = mixins[key])) { mixins[key] = Ext.ClassManager.get(cls); } } } // The target class and the required classes for this override are // ready, so we can apply the override now: cls = me.get(overriddenClassName); // We don't want to apply these: delete data.override; delete data.compatibility; delete data.requires; delete data.uses; Ext.override(cls, data); // This pushes the overridding file itself into Ext.Loader.history // Hence if the target class never exists, the overriding file will // never be included in the build. me.triggerCreated(className); if (uses) { // This "hides" from the Cmd auto-dependency scanner since // the reference is circular (Loader requires us). Ext['Loader'].addUsedClasses(uses); // get these classes too! } if (createdFn) { createdFn.call(cls, cls); // last but not least! } }; me.triggerExists(className, 2); if (!compat || Ext.checkVersion(compat)) { // Override the target class right after it's created me.onCreated(classReady, me, overriddenClassName); } return me; }
requires屬性下的js直接被加載,而uses下的js被加入usedclass方法,用以初始化完成後在加載
建立/配置`倉庫`,grid很是依賴的實例,很顯然,creat表明着建立,每次加載grid都會建立一個store在內存中...爲了達到複用目的(相似於create,show),可使用StoreManage進行管理
domcument.body的封裝,表明整個瀏覽界面(body,全部沒有renderto),主要用於方便佈局,一個頁面只有一個viewport
應用程序的封裝(相似於路由的全局封裝),包含了應用程序應該綁定的Models、Views和Controllers,能夠經過響應的屬性進行管理(其實等價於requires),其中view能夠被Controller管理(controller的效果依賴view的存在),因此這個地方須要描述Models和Controllers
固然了,application的配置又回在初始化時提早加載,因此是在view中使用requires分散壓力,仍是一口氣配置完成,就看需求了
修改後標準的mvc:
Application:應用程序關聯設置
Ext.define('app.Application', { extend: 'Ext.app.Application', name: 'app', stores: ['User'], controllers: ['User'], models:['User'], autoCreateViewport: true, launch: function() {} });
viewreport:body的封裝,無需在引用
Ext.define("app.view.Viewport", { extend: "Ext.container.Viewport", layout: "fit", items: { xtype:"userlist" } });
view:真正的視圖,徹底找不到業務邏輯,若是頁面須要修改,在此處
Ext.define("app.view.user.List", { extend: "Ext.grid.Panel", alias: 'widget.userlist', store: 'User', columns: [{ text: 'firstName', dataIndex: 'firstName' }, { text: 'lastName', dataIndex: 'lastName' }, { text: 'age', dataIndex: 'age' }, { text: 'eyeColor', dataIndex: 'eyeColor' }], initComponent: function() { this.callParent(); } });
controller:真正的邏輯層,能夠經過他來關聯views(緣由你懂得,實踐勝於理論),若是邏輯出錯,就在這裏,依賴選擇器
Ext.define('app.controller.User', { extend: 'Ext.app.Controller', views:['user.List'], init: function() { this.control({ 'userlist': { itemclick: this.userlistHighlight } }); }, userlistHighlight: function() { console.log('click el'); } });
至此mvc的方式就已經完成了,儘管聊過延遲加載,其實在mvc模式下,延遲加載的解決方案至關的糟糕-。-
根據官網的呆毛,進行嘗試
Application:應用程序關聯設置
Ext.application({ name: 'app', extend: 'app.Application', autoCreateViewport:'app.view.main.Main' });
view容器:view木有任何邏輯,但參與調用/綁定的設計,以減小工做量,此處有迷之`main`參數,木有加載配置
Ext.define('app.view.main.Main', { extend: 'Ext.container.Container', xtype: 'app-main', controller: 'main', viewModel: { type: 'main' }, layout: { type: 'border' }, items: [{ xtype: 'panel', bind: { title: '{name}' }, region: 'west', html: '<ul><li>This area is commonly used for navigation, for example, using a "tree" component.</li></ul>', width: 250, split: true, tbar: [{ text: 'Button', handler: 'onClickButton' }] },{ region: 'center', xtype: 'tabpanel', items:[{ title: 'Tab 1', html: '<h2>Content appropriate for the current navigation.</h2>' }] }] });
controller:全部的邏輯都在這裏,咱們能夠將alias註釋掉,作幾個小測試
Ext.define('app.view.main.MainController', { extend: 'Ext.app.ViewController', requires: [ 'Ext.window.MessageBox' ], // alias: 'controller.main', onClickButton: function () { Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this); }, onConfirm: function (choice) { if (choice === 'yes') { // } } });
vm:靜態數據,此處能夠添加各類get方法用以修改數據轉換的邏輯
Ext.define('app.view.main.MainModel', { extend: 'Ext.app.ViewModel', // alias: 'viewmodel.main', data: { name: 'app' } //TODO - add data, formulas and/or methods to support your view });
總之,vm+c分散了業務的代碼
以上是官網的呆毛,若是根據這種格式去寫第二個栗子就會發現,徹底運行不起來。。。八層是該類未被加載的意思,可是,官網的例子又是爲毛...
bootstrap.json-->能夠在該文件下看見一下內容
"app.view.main.MainController": { "idx": 17, "alias": ["controller.main"], "alternates": [] }, "app.view.main.MainModel": { "idx": 18, "alias": ["viewmodel.main"], "alternates": [] }
在這裏增長本身的測試項目,就能夠相關像官網同樣實現了
以上爲ext下的mvvm實現,感受也就是mvc+雙向綁定,不如angular這種舒服