概述
· ExtJs5能夠搭建Js的MVC框架,通過配置路由能夠通過左邊樹形菜單導航到所需的頁面,效果如下:
搭建JS框架
新建home.htm頁面作為ExtJs加載的主體頁面,頁面引入ExtJs需要的JS和ExtJs入口Js文件app.js
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>ExtJS演示</title> <script type="text/javascript" src="Ext/ext-all.js"></script> <script type="text/javascript" src="Ext/ext-locale-zh_CN.js"></script> <link rel="stylesheet" type="text/css" href="Ext/packages/ext-theme-crisp/build/resources/ext-theme-crisp-all_01.css"> <script type="text/javascript" src="app.js"></script> </head> <body> </body> </html>
app.js是ExtJs框架的入口,新建ExtJs中Application程序,指定所有新建ExtJs類的命名空間必須是MyApp開頭,類似 MyApp.***,另外在app.js同級目錄下新建app文件夾,里面新建文件夾view和viewmodel,這些文件夾的命名和規則必須是確定,不能任意修改,否則文件加載的時候,找不到相應的Js文件;
//ExtJs的入口,加載該Js之后,自動調用launch方法內容項 Ext.application({ name : 'MyApp', extend:'MyApp.Application', autoCreateViewport:'MyApp.view.main.Main', // controllers:['Users'], listen: { controller: { '#': { unmatchedroute: 'onUnmatchedRoute' } } }, onUnmatchedRoute: function(hash) { alert('Unmatched', hash); }, init:function(){ var me=this; me.setDefaultToken('all'); }, launch : function() { } });
在app目錄下,新建Application.js,命名MyApp.Application,代碼如下,切記定義Js組件的名稱,必須和文件路徑對應
Ext.define('MyApp.Application',{ extend:'Ext.app.Application', name:'MyApp', // stores:[ // 'UserStore@MyApp.store' // ] });
在app目錄下,新建文件夾view\main,里面新建main.js,主要繼承Ext.container.Container容器控件,負責頁面布局使用,頁面布局模式采用border使用,分為頭部、導航、中間頁面內容展示;
Ext.define('MyApp.view.main.Main',{ extend:'Ext.container.Container', xtype:'app-main', requires:['MyApp.view.main.MainController','MyApp.view.main.Header','MyApp.view.main.Navigation','MyApp.view.main.ContentPanel'], controller:'main', layout:{type:'border'}, items:[ {region:'north',xtype:'app-header'}, {region:'west',xtype:'app-navigation'}, {region:'center',xtype:'app-contentPanel'} ] });
在app\view\main,新建總部內容MainController.js,類型是Ext.app.ViewController。內容如下,主要負責Main.js的Action和hander的綁定,控制頁面的路由導航
var com={'message-view':'MyApp.view.message.MessageController','UserGrid':'MyApp.view.user.UserGridController'}; Ext.define('MyApp.view.main.MainController',{ extend:'Ext.app.ViewController', requires:[ 'Ext.window.MessageBox' ], alias:'controller.main', control:{ 'app-navigation':{ selectionchange:'onTreeNavSelectionChange' } }, onTreeNavSelectionChange:function(selModel,records) { var record=records[0]; console.log(record.getId()); if(record) this.redirectTo(record.getId()); }, routes: { ':id': { action: 'handleRout', before: 'beforeHandleRout' } }, handleRout: function (id) { console.log('Handle:'+id); var me=this, mainView = me.getView(), navigationTree = mainView.down('app-navigation'), contentPanel = mainView.down('app-contentPanel'), store=navigationTree.getStore(), node=store.getNodeById(id); contentPanel.removeAll(true), controlName=com[id]; Ext.create(controlName);//MyApp.view.message.MessageController var module = Ext.apply({}, { xtype: id, itemId: id, //glyph: node.get('glyph'), title: node.get('text') // tooltip: node.get('text') }); contentPanel.add(module); var text = node.get('text'), title = node.isLeaf() ? (node.parentNode.get('text') + ' - ' + text) : text; contentPanel.setTitle(title); //Ext.suspendLayouts(); //暫停布局 Ext.resumeLayouts(true); //恢復布局 }, beforeHandleRout: function (id, action) { //動態實例化controller action.stop(); var me=this, store=Ext.StoreMgr.get('NavigationStore'); node=store.getNodeById(id); if(node) { action.resume(); } else { Ext.Msg.alert( '路由跳轉失敗', '找不到id為' + id + ' 的組件. 界面將跳轉到應用初始界面', function() { me.redirectTo('all'); } ); action.stop(); } }, });
在app\view\main,新建頭部Header.js,內容如下
Ext.define('MyApp.view.main.Header',{ extend:'Ext.Container', xtype:'app-header', height:52, layout:{type:'hbox',align:'middle'}, items:[ {xtype:'component',html:'<h2>XX系統</h2>'}, {xtype:'component',html:'ExtJs實例',flex:1} ] });
在app\view\main,新建導航Navigation.js,內容如下,PS 樹形結構的id名稱要和視圖的xtype對應
Ext.define("MyApp.view.main.Navigation",{ extend:'Ext.tree.Panel', xtype:'app-navigation', rootVisible:false, userArrows:true, // hideHeaders:true, width:250, minWidth:100, split:true, collapsible:true, store:Ext.create('Ext.data.TreeStore', { id:'NavigationStore', root: { expanded: true, id:'all', text:'All', children: [ {text: "消息管理", id: "message-view", leaf: true}, {text: "用戶列表", id: "UserGrid", leaf: true} ] } }) });
在app\view\main,新建總部內容ContentPanel.js,內容如下
Ext.define('MyApp.view.main.ContentPanel',{ extend:'Ext.panel.Panel', xtype:'app-contentPanel', autoScroll:true });
在app\view\user,新建用戶頁面UserGrid.js,內容如下
Ext.define('MyApp.view.user.UserGrid', { extend: 'Ext.grid.Panel', xtype: 'UserGrid', title: '用戶列表', requires:['MyApp.store.UserStore'], store:Ext.create('MyApp.store.UserStore'), controller:'usergrid', initComponent:function(){ var me = this; me.columns = [ {xtype: 'rownumberer',header: '序號', width: 60, align: 'center'}, {xtype: 'rownumberer',header: '用戶名', width: 60, align: 'center'}, {xtype: 'rownumberer',header: '年齡', width: 60, align: 'center'}, ]; me.callParent(); }, width: 400, height:600, border:true, listeners:{ itemdblclick: { fn: 'userClick', scope: "controller" } } });
在app\view\user,新建用戶視圖控制器UserGridController.js,內容如下
Ext.define('MyApp.view.user.UserGridController',{ extend:'Ext.app.ViewController', alias:'controller.usergrid', requires:["MyApp.view.user.UserGrid"], userClick:function( view, record, item, index, e, eOpts){ alert('hello'+record.get('name')) } });
在app\model ,新建UserModel.js,內容如下
Ext.define('MyApp.model.UserModel', { extend: 'Ext.data.Model', fields: [ {name: 'name', type: 'string'}, {name: 'age', type: 'int'}, {name: 'phone', type: 'string'} ] });
在app\store,新建UserStore.js,內容如下
Ext.define('MyApp.store.UserStore', { extend: 'Ext.data.Store', model: 'MyApp.model.UserModel', autoLoad: true, alias:'user-store', proxy: { type: 'ajax', api: { read: 'data/users.json' }, reader: { type: 'json', rootProperty: 'users', successProperty: 'success' } } });
需要注意事項:
1、文件目錄必須按Ext.define的定義的順序建立,這個是默認約定的,否則找不到文件Js;
2、導航的id值必須是和新建的控件名稱的xtype類型對應,否則加載控件失敗;
3、ViewController和View綁定,在Js里面requires的內容項,默認會加載相應的Js文件;
4、如果提示,extjs Cannot read property 'isBufferedStore' of undefined,主要原因在於store內容為空導致的;
完整代碼如下