本文讲述extjs mvc的Helloworld,tabPanel,event,页面布局layout等内容。javascript
本页包含:MVC模式案例(一)~MVC模式案例(六),从搭建extjs mvc到点击按钮生成tab页,事件点击css
本文代码位置:http://download.csdn.net/download/xiaoliu123586/10156915html
代码使用idea打开便可,若是在windows下直接用浏览器打开index.html,加载data.json树文件会找不到,必须在某服务器里打开或者或者idea打开,前端
访问url相似:http://localhost:63342/extdemo/index.html?_ijt=8bt5l2b9lkvqhvs1gukmm1j5mkjava
而不是 file:///C:/Users/Mike/Desktop/extdemo/index.htmlajax
即将实现网页的布局有三部分组成:顶部标题、左侧菜单和右侧主题内容显示。这里咱们对案例的布局有个初步印象,方便从此咱们的进一步学习。json
了解了项目的最终效果,下面来看一下该案例最终的文件结构:bootstrap
文件结构能够看出,在整个项目中,app文件夹是咱们的主要工做目录,其中包含:controller(控制器)、model(数据模型)、store(数据集)、view(视图)。另外还有server文件夹,其主要目的是代替后台服务器为项目提供数据。这些内容咱们将在从此的文章中逐步讲解,今天咱们来看一下index.html和app.js这两个文件。
index.html文件代码:windows
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ExtJS学习:MVC模式案例</title> <link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="../extjs/examples/shared/example.css" /> <script type="text/javascript" src="../extjs/bootstrap.js"></script> <script type="text/javascript" src="../extjs/locale/ext-lang-zh_CN.js"></script> <script type="text/javascript" src="app.js"></script> </head> <body> <iframe id='contentIframe' name='contentIframe' style='height:100%;width:100%' frameborder="no"></iframe> </body> </html>
这个文件主要的目的就是对ExtJS框架文件的引用,这里咱们不作过多的介绍。
app.js文件代码:后端
Ext.onReady(function(){ //开启悬浮提示功能 Ext.QuickTips.init(); //开启动态加载 Ext.Loader.setConfig({ enabled: true }); //建立应用程序的实例 Ext.application({ //设定命名空间 name: 'Demo', //指定配置选项,设置相应的路径 appFolder: 'app', //加载控制器 controllers: ['demoController'], //自动加载和实例化Viewport文件 autoCreateViewport: true }); });
app.js文件能够当作是对咱们整个项目的全局设置,其中咱们须要注意的有:
(1)Ext.Loader.setConfig帮咱们开启了自动加载的功能,这个功能默认是不开启的,须要咱们手动开启,不然之后开发的不少文件都会找不到,报错。
(2)name: ‘Demo’给项目规定了一个命名空间,它将做为一个全局变量应用于整个项目中,帮助咱们识别属于本项目的应用文件。
(3)appFolder: ‘app’这个配置项,帮咱们指定到app文件夹中。
ExtjS框架怎么使用MVC模式对代码进行布局。
到目前为止咱们现有的文件只有根目录下的index.html和app.js两个文件,不具备任何的实际意义。下面咱们开始着手建立咱们的项目,让它可以实实在在的展示在咱们的浏览器中。首先,咱们在根目录下建立app文件夹,而后在app文件夹下建立controller和view两个文件夹,分别存放咱们的控制器文件和视图文件。
VeiwPort表明整个浏览器显示区域,该对象渲染到页面的body区域,并会随着浏览器显示区域的大小自动改变,一个页面中只能有一个ViewPort 实例。下面咱们在view文件夹中建立Viewport.js文件,而后添加以下代码:
Ext.define('Demo.view.Viewport', { extend: 'Ext.container.Viewport', //布局方式:border layout: 'border', items: [{ title:'ExtJS案例', collapisble: true, region:'north', height: 100, html: '<br><center><font size=5>MVC模式实现的ExtJS案例</font><br><font size=2>源码来源:ITLee博客</font></center>' },{ title: '功能菜单', region: 'west', width: 180, split: true, collapisble: true, html:'这里是菜单部分' }, { id: 'mainContent', title: '主题内容显示', layout: 'fit', region: 'center', collapisble: true, contentEl: 'contentIframe' }] });
在Viewport中咱们用border的布局方式将整个网页分为三个部分:头部(north)、左部(west)、主题部分(center)。
控制器是整个应用程序的关键,他负责监听事件,并对某些时间作出相应的动做。如今咱们在controller文件夹下建立一个控制器,命名为demoController.js(这里的命名应该与app.js文件中加载的控制器名称相同),而后咱们为该文件添加如下代码:
Ext.define('Demo.controller.demoController', { extend: 'Ext.app.Controller', //将Viewport.js添加到控制器 views: ['Viewport'] });
在控制器中咱们经过views配置项,将所需视图加载到控制器中。如今咱们经过浏览器就能够对项目进行查看了,查看效果以下:
至此,咱们对网页的布局就算是完成了,但愿对你们有所帮助。下一讲咱们将讲解树形菜单的实现。
接下来,咱们在view文件夹中添加一个menuTree.js文件,用来做为树形菜单组件。为该文件添加如下代码:
Ext.define('Demo.view.menuTree', { extend: 'Ext.tree.Panel', alias: 'widget.menutree', border: false, //规定锚连接地址的显示区域 hrefTarget: 'mainContent', //是否显示根节点 rootVisible: false, //数据集 store: 'menuStore', //菜单样式 bodyStyle: { background: '#ffc', padding: '10px' } });
这样咱们就建立了一个菜单的组件,可是,如今咱们的菜单还不能正常工做,由于菜单中尚未填充数据。ExtJS4中咱们用单独的一个文件来建立数据模型和数据集,在建立数据集前咱们首先建立数据模型。在app文件夹下建立model文件夹,而且在该文件夹下建立menuModel.js文件,为该文件添加如下代码:
Ext.define('Demo.model.menuModel', { extend: 'Ext.data.Model', fields:[ {name:'id', type:'int'}, {name:'pid', type:'int'}, {name:'text', type:'varchar'}, //type为布尔型时,后面的默认值是必须写的,要不会出错 {name:'leaf', type:'boolean', defaultValue: true}, {name: 'url', type:'varchar'} ] });
有了数据模型,接下来咱们建立store文件夹,以及在该文件夹下建立menuStore.js文件,添加下面的代码:
Ext.define("Demo.store.menuStore",{ extend:'Ext.data.TreeStore', defaultRoodId:'root', //requires: 'Demo.model.menuModel',//我加了这两行,会报错 //model: 'Demo.model.menuModel', proxy:{ type:'ajax', url:'./server/data.json', reader:'json', autoLoad:true } });
数据集和数据模型都有了,那么咱们怎么给菜单添加数据呢?通常状况下,菜单所需的数据都是有后台服务器提供,由于咱们这里主要讲解ExtJS的知识,尽可能不去涉及后端的东西,咱们能够用json格式模拟后台数据输出。如今,咱们在根目录下建立server文件夹,在该文件夹下建立一个data.json的文件用来为前端提供数据:
[ {"id":"2", "pid":"1", "text":"用户管理", "leaf":"0", "url":"http:\/\/www.lihuai.net", "children":[{ "id":"5", "pid":"2", "text":"基本信息", "leaf":"1", "url":"http:\/\/www.sogou.com", "children":""},{ "id":"11", "pid":"2", "text":"信息管理", "leaf":"1", "url":"http:\/\/www.sogou.com", "children":""},{ "id":"12", "pid":"2", "text":"添加用户", "leaf":"1", "url":"http:\/\/www.sogou.com", "children":""}]}, {"id":"3", "pid":"1", "text":"产品管理", "leaf":"0", "url":"http:\/\/www.so.com", "children":[{ "id":"7", "pid":"3", "text":"产品信息", "leaf":"1", "url":"http:\/\/www.so.com", "children":""},{ "id":"8", "pid":"3", "text":"产品添加", "leaf":"1", "url":"http:\/\/www.so.com", "children":""}]} ]
为了简单起见,每一个节点的url地址咱们用简单的网页替代。万事俱备,只差加载了。那么,怎么才能将咱们写好的菜单组件加载到咱们的项目中呢?
首先,修改咱们的Viewport.js文件,将菜单组件添加到整个视图中,修改后的代码以下:
Ext.define('Demo.view.Viewport', { extend: 'Ext.container.Viewport', //布局方式 layout: 'border', items: [{ title:'ExtJS案例', collapisble: true, region:'north', height: 100, html: '<br><center><font size=5>MVC模式实现的ExtJS案例</font><br><font size=2>源码来源:ITLee博客</font></center>' },{ title: '功能菜单', region: 'west', width: 180, split: true, collapisble: true, //这里是修改的部分 items:[{ xtype: 'menutree' }] }, { id: 'mainContent', title: '主题内容显示', layout: 'fit', region: 'center', collapisble: true, contentEl: 'contentIframe' }] });
接下来,修改demoController.js文件,实现对菜单组件的加载,修改后的代码:
Ext.define('Demo.controller.demoController', { extend: 'Ext.app.Controller', views: ['Viewport','menuTree'], stores: ['menuStore'], model: ['menuModel'] });
如今,用浏览器查看咱们的案例,左侧已经显示出菜单栏了,效果以下图:
当咱们点击树形节点的时候,发现右侧主题部分并无显示网页内容,这是由于咱们尚未为节点添加监听事件的缘由。具体如何添加切换页面的效果,下一讲咱们将会详细讲解。
咱们基本实现了MVC模式布局ExtJS项目的目的,而且在浏览器中也能够看到最为常见的网页布局结构。可是,做为WEB开发者,并非可以实现网页布局就算是完成任务了,咱们还须要实现必定的功能。在这一讲中,咱们将实现当点击ExtJS菜单节点的时候,网页主题部分显示相对应的内容。
本讲咱们不会添加新的文件,只是对原来的文件进行修改便可。前面咱们说过,控制器的主要做用是监听事件,控制逻辑。因此,咱们今天主要修改demoController.js这个文件,为咱们的项目添加切换页面的功能。
demoController.js文件代码:
添加对menuTree组件的鼠标点击事件进行监听,修改后的代码:
Ext.define('Demo.controller.demoController', { extend:'Ext.app.Controller', views: ['Viewport','menuTree'], stores: ['menuStore'], model: ['menuModel'], //经过init函数来监听视图事件,控制视图与控制器的交互 init:function() { //init函数经过this.control来负责监听 this.control({ //被监听的组件的别名 'menutree': { //监听鼠标点击事件,点击后调用changePage方法 itemclick:this.changePage, } }); }, changePage:function(){ alert('success'); } });
刷新页面,点击菜单几点,弹出success说明咱们监听事件成功。下面咱们继续修改changePage方法,实现对主体内容部分页面的切换功能。
changePage:function(view, rec, item, index, e){ //获取url地址 var url = rec.get('url'); //获取当前节点信息 var title = rec.get('text'); //将主体内容部分的url地址指定为咱们获取到的url Ext.getDom('contentIframe').src = url; //将主体内容框的标题设置为咱们获取的节点信息 Ext.getCmp('mainContent').setTitle(title); }
经过对changePage方法的修改,刷新页面,当咱们再次点击节点的时候,右侧主体内容部分将显示对应url的页面信息,大功告成。
要实现右键菜单的功能,首先咱们须要添加一个菜单组件,在view文件夹中新建contextMenu.js文件,该文件中添加如下代码:
Ext.define('Demo.view.contextMenu', { extend: 'Ext.menu.Menu', alias: 'widget.contextmenu', float: true, items: [{ xtype: 'button', text: '添加', action: 'add', iconCls: 'leaf' }, { xtype: 'button', text: '删除', action: 'del', iconCls: 'leaf' }, { xtype: 'button', text: '编辑', action: 'edit', iconCls: 'leaf' }] });
正如咱们前面所说的,添加组件后须要在控制器中进行加载,不然ExtJS的自动加载机制将不能找到咱们的文件,下面修改demoController.js文件的view配置项,修改后的代码以下:
Ext.define('Demo.controller.demoController', { extend: 'Ext.app.Controller', //此次的修改在这里,给view配置项添加“contextMenu” views: ['Viewport','menuTree','contextMenu'], stores: ['menuStore'], model: ['menuModel'], //经过init函数来监听视图事件,控制视图与控制器的交互 init: function() { //init函数经过this.control来负责监听 this.control({ //被监听的组件的别名 'menutree': { //监听鼠标点击事件,点击后调用changePage方法 itemclick: this.changePage, } }); }, changePage:function(view, rec, item, index, e){ //获取url地址 var url = rec.get('url'); //获取当前节点信息 var title = rec.get('text'); //将主体内容部分的url地址指定为咱们获取到的url Ext.getDom('contentIframe').src = url; //将主体内容框的标题设置为咱们获取的节点信息 Ext.getCmp('mainContent').setTitle(title); } });
作完以上工做后,接下来就是为咱们的menuTree组件添加右键监听事件了,修改控制器文件demoController.js:
Ext.define('Demo.controller.demoController', { extend: 'Ext.app.Controller', views: ['Viewport','menuTree','contextMenu'], stores: ['menuStore'], model: ['menuModel'], //经过init函数来监听视图事件,控制视图与控制器的交互 init: function() { //init函数经过this.control来负责监听 this.control({ //被监听的组件的别名 'menutree': { //监听鼠标点击事件,点击后调用changePage方法 itemclick: this.changePage, //监听鼠标右键事件,点击后调用contextMenu方法 itemcontextmenu: this.contextMenu } }); }, //页面切换方法 changePage:function(view, rec, item, index, e){ //获取url地址 var url = rec.get('url'); //获取当前节点信息 var title = rec.get('text'); //将主体内容部分的url地址指定为咱们获取到的url Ext.getDom('contentIframe').src = url; //将主体内容框的标题设置为咱们获取的节点信息 Ext.getCmp('mainContent').setTitle(title); }, //显示右键菜单方法 contextMenu:function(tree, record, item, index, e, eOpts){ //阻止浏览器默认右键事件 e.preventDefault(); e.stopEvent(); //显示右键菜单 var view = Ext.widget('contextmenu'); view.showAt(e.getXY()); } });
在demoController.js文件中添加以上代码后,刷新页面,在菜单节点上点击右键,看到以下效果图:
如今,咱们整个案例教程就结束了,虽然还有不少功能没实现,若是继续扩展的话,怕是永远也讲不完了,呵呵,主要目的仍是为ExtJS的新手们起一个引导的做用,但愿对你们有所帮助。
以上代码的状况下,改为点击菜单,生成tab的状况
修改demoController的changePage方法
changePage:function(view, rec, item, index, e){ var title = rec.get('text'); var leaf = rec.get('leaf'); var tabPanel = Ext.getCmp('mainContent'); //子节点才能打开,父节点不设置响应 if(leaf==false){ return; } //以title值设置为tab的id,打开时,有就使tab active,无则新建tab var newTab = tabPanel.getChildByElement(title); if (newTab == null) { tabPanel.add({ id: title, title: title, html: '当前页面是 ' + title + '<br/><br/>', closable: true }); } tabPanel.setActiveTab(title); }
ViewPort.js里center布局的部分,改动以下
{ region: 'center', id: 'mainContent', xtype:'tabpanel', title: '主题内容显示', layout: 'fit', collapisble: true }
此时,data.json的id和pid属性能够去掉了(没使用到了)
data.json:
[ { "text":"用户管理", "leaf":"false", "url":"http://www.lihuai.net", "children":[ { "text":"基本信息", "leaf":"true", "url":"http://www.sogou.com", "children":"" }, { "text":"信息管理", "leaf":"true", "url":"http://www.sogou.com", "children":"" }, { "text":"添加用户", "leaf":"true", "url":"http://www.sogou.com", "children":"" }]}, { "text":"产品管理", "leaf":"false", "url":"http://www.so.com", "children":[ { "text":"产品信息", "leaf":"true", "url":"http://www.so.com", "children":"" }, { "text":"产品添加", "leaf":"true", "url":"http://www.so.com", "children":"" }]} ]
注意,若是须要树哪一个节点默认展开,就在节点下配置"expanded:true" ,即修改data.json文件
======================================================================================================================
参考自:http://blog.csdn.net/luckypeng/article/details/43151793
有略微修正。
一下是一些我的实际代码的贴出
Ext基本引入文件以下:
<script type="text/javascript" src="ext/ext-all.js"></script> <link rel="stylesheet" type="text/css" href="ext/theme-crisp/resources/theme-crisp-all.css" />